adding tuxbliki application
|
@ -0,0 +1,61 @@
|
|||
require 'rubygems'
|
||||
Gem.clear_paths
|
||||
Gem.path.unshift(File.join(File.dirname(__FILE__), "gems"))
|
||||
|
||||
require 'rake'
|
||||
require 'rake/rdoctask'
|
||||
require 'rake/testtask'
|
||||
require 'spec/rake/spectask'
|
||||
require 'fileutils'
|
||||
require 'merb-core'
|
||||
require 'rubigen'
|
||||
|
||||
$RAKE_ENV = true
|
||||
|
||||
Merb.load_dependencies
|
||||
|
||||
include FileUtils
|
||||
# # # Get Merb plugins and dependencies
|
||||
Merb::Plugins.rakefiles.each {|r| require r }
|
||||
|
||||
#
|
||||
#desc "Packages up Merb."
|
||||
#task :default => [:package]
|
||||
|
||||
desc "load merb_init.rb"
|
||||
task :merb_init do
|
||||
require 'merb-core'
|
||||
require File.dirname(__FILE__)+'/config/init.rb'
|
||||
end
|
||||
|
||||
task :uninstall => [:clean] do
|
||||
sh %{sudo gem uninstall #{NAME}}
|
||||
end
|
||||
|
||||
desc 'Run all tests, specs and finish with rcov'
|
||||
task :aok do
|
||||
sh %{rake rcov}
|
||||
sh %{rake specs}
|
||||
end
|
||||
|
||||
unless Gem.cache.search("haml").empty?
|
||||
namespace :haml do
|
||||
desc "Compiles all sass files into CSS"
|
||||
task :compile_sass do
|
||||
gem 'haml'
|
||||
require 'sass'
|
||||
puts "*** Updating stylesheets"
|
||||
Sass::Plugin.update_stylesheets
|
||||
puts "*** Done"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# SVN
|
||||
##############################################################################
|
||||
|
||||
desc "Add new files to subversion"
|
||||
task :svn_add do
|
||||
system "svn status | grep '^\?' | sed -e 's/? *//' | sed -e 's/ /\ /g' | xargs svn add"
|
||||
end
|
|
@ -0,0 +1,60 @@
|
|||
class Albums < Application
|
||||
def index
|
||||
@albums = Album.find(:all)
|
||||
@tags = Album.popular_tags(30)
|
||||
display @albums
|
||||
end
|
||||
|
||||
def show
|
||||
@album = Album.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
raise NotFound unless @album
|
||||
display @album
|
||||
end
|
||||
|
||||
def new
|
||||
only_provides :html
|
||||
@secondary_title = 'Create an album'
|
||||
@album = Album.new(params[:album])
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
@album = Album.new(params[:album])
|
||||
if @album.save
|
||||
redirect url(:album, @album.name.gsub(/ /, '_'))
|
||||
else
|
||||
@secondary_title = 'Create an album'
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
only_provides :html
|
||||
@album = Album.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
@secondary_title = 'Update an album'
|
||||
raise NotFound unless @album
|
||||
render
|
||||
end
|
||||
|
||||
def update
|
||||
@album = Album.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
raise NotFound unless @album
|
||||
@secondary_title = 'Update an album'
|
||||
if @album.update_attributes(params[:album])
|
||||
redirect url(:album, @album.name.gsub(/ /, '_'))
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@album = Album.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
raise NotFound unless @album
|
||||
if @album.destroy
|
||||
redirect url(:albums)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
class Application < Merb::Controller
|
||||
cattr_accessor :current_author_id
|
||||
before :set_current_author_id
|
||||
|
||||
def logged_in?
|
||||
!session[:author_id].nil?
|
||||
end
|
||||
|
||||
def set_current_author_id
|
||||
self.current_author_id = session[:author_id]
|
||||
end
|
||||
|
||||
def get_photo_version(width, height)
|
||||
key = "photo_#{@photo.id}_#{width}_#{height}"
|
||||
img = Cache.get(key)
|
||||
|
||||
File.open("#{@photo.base_directory}/#{@photo.filename}", "r") do |f|
|
||||
img = Magick::Image.from_blob(f.read).first.resize_to_fit(width, height)
|
||||
Cache.put(key, img)
|
||||
end if img.nil?
|
||||
|
||||
img
|
||||
end
|
||||
end
|
|
@ -0,0 +1,69 @@
|
|||
class Authors < Application
|
||||
def index
|
||||
@authors = Author.find :all, :order => 'name ASC'
|
||||
@secondary_title = 'Authors'
|
||||
display @authors
|
||||
end
|
||||
|
||||
def show
|
||||
@author = Author.find_by_name(params[:id])
|
||||
raise NotFound unless @author
|
||||
@secondary_title = "#{@author.name}'s page"
|
||||
display @author
|
||||
end
|
||||
|
||||
def new
|
||||
only_provides :html
|
||||
@author = Author.new
|
||||
@secondary_title = "It's better than herpes!"
|
||||
render
|
||||
end
|
||||
|
||||
def edit
|
||||
only_provides :html
|
||||
@author = Author.find_by_name(params[:id])
|
||||
raise NotFound unless @author
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
@author = Author.new(params[:author])
|
||||
@invitation = Invitation.find_by_code params[:invitation_code]
|
||||
if @invitation.nil?
|
||||
flash[:notice] = 'You are not invited, you will need to try again later.'
|
||||
render :new
|
||||
elsif @author.save
|
||||
flash[:notice] = 'Great success!'
|
||||
@invitation.destroy
|
||||
redirect url(:author, :id => @author.name)
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@author = Author.find_by_name(params[:id])
|
||||
raise NotFound unless @author
|
||||
if @author.update_attributes(params[:author])
|
||||
flash[:notice] = 'Great success!'
|
||||
redirect url(:author, :id => @author.name)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@author = Author.find_by_name(params[:id])
|
||||
raise NotFound unless @author
|
||||
if @author.destroy!
|
||||
flash[:notice] = 'The author was destroyed.'
|
||||
if @author.id == session[:author_id]
|
||||
redirect url(:delete_session, :id => session[:author_id])
|
||||
else
|
||||
redirect url(:author)
|
||||
end
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
class Comments < Application
|
||||
def new
|
||||
only_provides :html
|
||||
@page = Page.find_by_name(params[:page_id].gsub(/_/, ' '))
|
||||
raise NotFound unless @page
|
||||
@comment = Comment.new
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
@page = Page.find_by_name(params[:page_id].gsub(/_/, ' '))
|
||||
raise NotFound unless @page
|
||||
@comment = Comment.new(params[:comment])
|
||||
@comment.page_id = @page.id
|
||||
if @comment.save
|
||||
flash[:notice] = 'Great success!'
|
||||
redirect url(:page, :id => params[:page_id])
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@comment = Comment.find(params[:id])
|
||||
raise NotFound unless @comment
|
||||
@page = @comment.page
|
||||
if @comment.destroy!
|
||||
flash[:notice] = 'Comment was destroyed.'
|
||||
redirect url(:page, :id => @page.name.gsub(/ /, '_'))
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class Exceptions < Application
|
||||
# handle NotFound exceptions (404)
|
||||
def not_found
|
||||
@page_title = 'Error 404'
|
||||
@secondary_title = 'Document Not Found'
|
||||
render :format => :html
|
||||
end
|
||||
|
||||
# handle NotAcceptable exceptions (406)
|
||||
def not_acceptable
|
||||
@page_title = 'Error 500'
|
||||
@secondary_title = 'Application Exception'
|
||||
render :format => :html
|
||||
end
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
class Invitations < Application
|
||||
def new
|
||||
only_provides :html
|
||||
@invitation = Invitation.new(params[:invitation])
|
||||
@secondary_title = 'Invite your friends!'
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
@invitation = Invitation.new(params[:invitation])
|
||||
if @invitation.save
|
||||
m = Merb::Mailer.new :to => @invitation.recipient,
|
||||
:from => 'invitations@penguincoder.org',
|
||||
:subject => 'TuxBliki Invitation!',
|
||||
:body => partial('invitation', :format => 'text')
|
||||
m.deliver!
|
||||
flash[:notice] = "You just sent an invitation!"
|
||||
redirect url(:authors)
|
||||
else
|
||||
@secondary_title = 'Invite your friends!'
|
||||
render :new
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
class News < Application
|
||||
def index
|
||||
ncount = Page.count :conditions => [ 'published = ?', true ]
|
||||
@page = params[:page].to_i
|
||||
per_page = 5
|
||||
@page_count = (ncount.to_f / per_page.to_f).ceil.to_i
|
||||
@page = 0 if @page >= @page_count
|
||||
@page_title = 'Blogging!'
|
||||
@news = Page.find :all, :limit => per_page, :offset => (@page * per_page), :conditions => [ 'published = ?', true ], :order => 'created_at DESC'
|
||||
@oldest_date = Page.find(:first, :order => 'created_at ASC').created_at rescue nil
|
||||
@tags = Page.popular_tags(30)
|
||||
render
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
class Node < Application
|
||||
def index
|
||||
redirect('/')
|
||||
end
|
||||
|
||||
def show
|
||||
page = Page.find_by_nid(params[:id])
|
||||
raise NotFound unless page
|
||||
purl = url(:page, :id => page.name.gsub(/ /, '_'))
|
||||
Merb.logger.info("Permenant Redirect Drupal Node to #{purl}")
|
||||
self.status = 301
|
||||
headers['Location'] = purl
|
||||
return "<html><body>You are being <a href=\"#{purl}\">redirected</a>.</body></html>"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,72 @@
|
|||
class Pages < Application
|
||||
def index
|
||||
@pages = Page.find :all, :order => 'name ASC', :conditions => [ 'published = ?', false ]
|
||||
@secondary_title = 'Wiki Pages. En Masse.'
|
||||
@tags = Page.popular_tags(30)
|
||||
display @pages
|
||||
end
|
||||
|
||||
def show
|
||||
@page = Page.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
if @page.nil?
|
||||
flash[:error] = "That page does not exist. You can now create it."
|
||||
redirect url(:new_page, :new_name => params[:id])
|
||||
else
|
||||
@comments = @page.comments
|
||||
@secondary_title = @page.name
|
||||
display @page
|
||||
end
|
||||
end
|
||||
|
||||
def new
|
||||
@page_title = 'Make a new page'
|
||||
only_provides :html
|
||||
@page = Page.new
|
||||
if params[:new_name]
|
||||
flash.now[:notice] = 'That page does not exist, but you can create it.'
|
||||
@page.name = params[:new_name].gsub(/_/, ' ')
|
||||
end
|
||||
render
|
||||
end
|
||||
|
||||
def edit
|
||||
@page_title = 'Update page'
|
||||
only_provides :html
|
||||
@page = Page.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
raise NotFound unless @page
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
@page = Page.new(params[:page])
|
||||
if @page.save
|
||||
flash[:notice] = "Great success!"
|
||||
redirect url(:page, :id => @page.name.gsub(/ /, '_'))
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@page = Page.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
raise NotFound unless @page
|
||||
if @page.update_attributes(params[:page])
|
||||
flash[:notice] = "Great success!"
|
||||
redirect url(:page, :id => @page.name.gsub(/ /, '_'))
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@page = Page.find_by_name(params[:id].gsub(/_/, ' '))
|
||||
raise NotFound unless @page
|
||||
if @page.destroy!
|
||||
flash[:notice] = "The page was successfully destroyed."
|
||||
redirect url(:page)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
class Permissions < Application
|
||||
def show
|
||||
@author = Author.find(params[:id])
|
||||
raise NotFound unless @author
|
||||
@permissions = @author.permissions
|
||||
@secondary_title = "Permissions for #{@author.name}"
|
||||
render
|
||||
end
|
||||
|
||||
def edit
|
||||
only_provides :html
|
||||
@author = Author.find(params[:id])
|
||||
raise NotFound unless @author
|
||||
@permissions = Permission.find :all, :order => 'name ASC'
|
||||
@secondary_title = "Change permissions for #{@author.name}"
|
||||
render
|
||||
end
|
||||
|
||||
def update
|
||||
@author = Author.find(params[:id])
|
||||
raise NotFound unless @author
|
||||
@permissions = Permission.find(params[:permissions])
|
||||
@author.permissions = @permissions
|
||||
redirect url(:permission, @author)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,41 @@
|
|||
class PhotoTags < Application
|
||||
def index
|
||||
redirect url(:tags)
|
||||
end
|
||||
|
||||
def show
|
||||
@photo = Photo.find(params[:id])
|
||||
@editable = !params[:editable].nil?
|
||||
partial 'photo_tags'
|
||||
end
|
||||
|
||||
def create
|
||||
@photo = Photo.find(params[:photo_tag][:photo_id]) rescue nil
|
||||
raise NotFound unless @photo
|
||||
|
||||
params[:tags].split.each do |tag_name|
|
||||
t = Tag.find_by_name(tag_name) rescue nil
|
||||
t ||= Tag.create :name => tag_name
|
||||
pt = PhotoTag.new(params[:photo_tag])
|
||||
pt.tag = t
|
||||
pt.save
|
||||
end
|
||||
|
||||
@editable = true
|
||||
partial 'photo_tags'
|
||||
end
|
||||
|
||||
def destroy
|
||||
@photo_tag = PhotoTag.find(params[:id])
|
||||
raise NotFound unless @photo_tag
|
||||
@photo = @photo_tag.photo
|
||||
raise NotFound unless @photo
|
||||
if @photo_tag.destroy
|
||||
@editable = true
|
||||
partial 'photo_tags'
|
||||
else
|
||||
render :text => @photo_tag.errors.collect { |e| e.to_s }.join(', '),
|
||||
:status => 500
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,88 @@
|
|||
class Photos < Application
|
||||
def index
|
||||
redirect url(:albums)
|
||||
end
|
||||
|
||||
def show
|
||||
@photo = Photo.find_by_id(params[:id])
|
||||
raise NotFound unless @photo
|
||||
@secondary_title = h(@photo.filename)
|
||||
|
||||
img = get_photo_version(600, 600)
|
||||
@width = img.columns
|
||||
@height = img.rows
|
||||
|
||||
render
|
||||
end
|
||||
|
||||
def new
|
||||
only_provides :html
|
||||
@photo = Photo.new(params[:photo])
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
@photo = Photo.new(params[:photo])
|
||||
if params[:photo][:album_id].to_i == 0
|
||||
album = (Album.find_by_name(params[:photo][:album_id]) rescue nil)
|
||||
raise NotFound unless album
|
||||
@photo.album = album
|
||||
end
|
||||
if @photo.save
|
||||
redirect url(:photo, @photo)
|
||||
else
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
only_provides :html
|
||||
@photo = Photo.find_by_id(params[:id])
|
||||
raise NotFound unless @photo
|
||||
render
|
||||
end
|
||||
|
||||
def update
|
||||
@photo = Photo.find_by_id(params[:id])
|
||||
raise NotFound unless @photo
|
||||
@photo.attributes = params[:photo]
|
||||
if params[:photo][:album_id].to_i == 0
|
||||
album = (Album.find_by_name(params[:photo][:album_id]) rescue nil)
|
||||
raise NotFound unless album
|
||||
@photo.album = album
|
||||
end
|
||||
if @photo.save
|
||||
redirect url(:photo, @photo)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@photo = Photo.find_by_id(params[:id])
|
||||
raise NotFound unless @photo
|
||||
if @photo.destroy
|
||||
redirect url(:photos)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
def thumbnail
|
||||
only_provides :html
|
||||
@photo = Photo.find(params[:id])
|
||||
raise NotFound unless @photo
|
||||
send_data get_photo_version(150, 150).to_blob,
|
||||
:filename => @photo.filename, :disposition => 'inline',
|
||||
:type => @photo.content_type
|
||||
end
|
||||
|
||||
def screen
|
||||
only_provides :html
|
||||
@photo = Photo.find(params[:id])
|
||||
raise NotFound unless @photo
|
||||
send_data get_photo_version(600, 600).to_blob,
|
||||
:filename => @photo.filename, :disposition => 'inline',
|
||||
:type => @photo.content_type
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
class Sessions < Application
|
||||
def new
|
||||
only_provides :html
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
author = Author.authenticate(params[:username], params[:password])
|
||||
if author
|
||||
session[:author_id] = author.id
|
||||
flash[:notice] = "Welcome back #{author.name}"
|
||||
redirect '/'
|
||||
else
|
||||
flash[:error] = 'Login failed.'
|
||||
render :new
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
redirect '/'
|
||||
end
|
||||
|
||||
def delete
|
||||
session[:author_id] = nil
|
||||
flash[:notice] = "You have logged out"
|
||||
redirect '/'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,61 @@
|
|||
class Tags < Application
|
||||
def index
|
||||
@tags = Tag.popular_tags
|
||||
@secondary_title = 'Tag Cloud'
|
||||
display @tags
|
||||
end
|
||||
|
||||
def show
|
||||
@tag = Tag.find_by_name(params[:id])
|
||||
raise NotFound unless @tag
|
||||
@pages = @tag.pages
|
||||
@albums = @tag.albums
|
||||
@secondary_title = "Content tagged with #{@tag.name}"
|
||||
display @tag
|
||||
end
|
||||
|
||||
def new
|
||||
redirect '/'
|
||||
end
|
||||
|
||||
def edit
|
||||
only_provides :html
|
||||
@tag = Tag.find_by_name(params[:id])
|
||||
raise NotFound unless @tag
|
||||
render
|
||||
end
|
||||
|
||||
def create
|
||||
redirect '/'
|
||||
end
|
||||
|
||||
def update
|
||||
@tag = Tag.find_by_name(params[:id])
|
||||
raise NotFound unless @tag
|
||||
if @tag.update_attributes(params[:tag])
|
||||
flash[:notice] = 'The tag was updated.'
|
||||
redirect url(:tag, :id => @tag.name)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
def delete
|
||||
@tag = Tag.find_by_name(params[:id])
|
||||
raise NotFound unless @tag
|
||||
if @tag.destroy
|
||||
flash[:notice] = "The tag #{@tag.name} was destroyed."
|
||||
redirect url(:tag)
|
||||
else
|
||||
raise BadRequest
|
||||
end
|
||||
end
|
||||
|
||||
def auto_complete
|
||||
@phrase = params[:id].split.last
|
||||
@tags = Tag.find :all, :limit => 15, :order => 'name ASC',
|
||||
:conditions => [ 'name LIKE ?', "%#{@phrase}%" ]
|
||||
@tags.<< Tag.new(:name => @phrase) unless @tags.detect { |t| t.name == @phrase }
|
||||
partial 'tags/tag_autocomplete_results', :read_only => true
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module AlbumsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module AuthorsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module CommentsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,105 @@
|
|||
module Merb
|
||||
module GlobalHelpers
|
||||
def nl2br(str)
|
||||
str.gsub(/\n/, '<br />')
|
||||
end
|
||||
|
||||
def error_messages_for(obj)
|
||||
obj = instance_variable_get("@#{obj.to_s}") if obj.is_a?(Symbol)
|
||||
return nil if obj.errors.nil? or obj.errors.empty?
|
||||
res = []
|
||||
res << "<br /><div id='errorExplanation'>"
|
||||
res << "<p>The following errors prevented the model from being saved:</p>"
|
||||
res << "<ol>"
|
||||
obj.errors.each do |field, msg|
|
||||
res << "<li>#{msg}</li>"
|
||||
end
|
||||
res << "</ol>"
|
||||
res << "</div>"
|
||||
res << "<br />"
|
||||
res.join
|
||||
end
|
||||
|
||||
def show_page_description(page)
|
||||
page_cache = Cache.get(page.cache_name)
|
||||
if page_cache.nil?
|
||||
redcloth_opts = [
|
||||
:textile,
|
||||
:block_textile_prefix,
|
||||
:block_textile_lists,
|
||||
:inline_textile_code,
|
||||
:inline_textile_link,
|
||||
:inline_textile_image,
|
||||
:inline_textile_span,
|
||||
:glyphs_textile
|
||||
]
|
||||
desc = h(page.description.to_s).to_s.gsub(/\"\;/, '"')
|
||||
# i need pre/code block together... because i code :)
|
||||
desc.gsub!("<pre><code>", "<pre><code>")
|
||||
desc.gsub!("</pre></code>", "</pre></code>")
|
||||
rc = RedCloth.new(desc)
|
||||
rc.no_span_caps = true
|
||||
rc.filter_styles = true
|
||||
page_cache = rc.to_html(redcloth_opts).gsub(Page.wiki_word_pattern) do |match|
|
||||
pg_name = $1
|
||||
if Page.exists?(pg_name)
|
||||
"<a class='wiki_link' style='color: #00F;' href='#{url(:page, pg_name.gsub(/ /, '_'))}'>#{pg_name}</a>"
|
||||
else
|
||||
"<a class='missing_wiki_link' rel='nofollow' style='color: #00F;' href='#{url(:new_page, :new_name => pg_name.gsub(/ /, '_'))}'>#{pg_name}</a>?"
|
||||
end
|
||||
end
|
||||
Cache.put(page.cache_name, page_cache)
|
||||
end
|
||||
page_cache
|
||||
end
|
||||
|
||||
def show_page_link(page)
|
||||
"<a href='#{url(:page, :id => page.name.gsub(/ /, '_'))}'>#{page.name}</a>"
|
||||
end
|
||||
|
||||
def tag_cloud(tags)
|
||||
max = 0
|
||||
tags.each { |tag| max = tag.count.to_i if tag.count.to_i > max }
|
||||
min = max
|
||||
tags.each { |tag| min = tag.count.to_i if tag.count.to_i < min }
|
||||
divisor = ((max - min) / tag_cloud_styles.size) + 1
|
||||
tags.collect { |t| "<span class='#{tag_cloud_styles[(t.count.to_i - min) / divisor]}'><a href='#{url(:tag, :id => t.name)}'>#{t.name}</a></span>" }.join(' ')
|
||||
end
|
||||
|
||||
def tag_cloud_styles
|
||||
%w(tag_cloud_1 tag_cloud_2 tag_cloud_3 tag_cloud_4 tag_cloud_5 tag_cloud_6 tag_cloud_7 tag_cloud_8 tag_cloud_9 tag_cloud_10 tag_cloud_11 tag_cloud_12)
|
||||
end
|
||||
|
||||
def allowed_to?(name, obj = nil)
|
||||
return false if session[:author_id].nil?
|
||||
@author_for_permissions ||= Author.find(session[:author_id])
|
||||
has_base = Permission.author_has_permission_to?(name, @author_for_permissions)
|
||||
if obj and obj.respond_to?('author_id') and obj.author_id != session[:author_id]
|
||||
has_base and Permission.author_has_permission_to?("any_#{name}", @author_for_permissions)
|
||||
else
|
||||
has_base
|
||||
end
|
||||
end
|
||||
|
||||
def block_to_partial(partial_name, options = {}, &block)
|
||||
options.merge!(:body => capture(&block))
|
||||
concat(partial(partial_name, :locals => options), block.binding)
|
||||
end
|
||||
|
||||
def photo_url(photo)
|
||||
"/photos/#{photo.id}/#{photo.filename}"
|
||||
end
|
||||
|
||||
def screen_photo_url(photo)
|
||||
url(:controller => 'photos', :action => 'screen', :id => photo.id)
|
||||
end
|
||||
|
||||
def thumbnail_photo_url(photo)
|
||||
url(:controller => 'photos', :action => 'thumbnail', :id => photo.id)
|
||||
end
|
||||
|
||||
def indicator
|
||||
"<img src='/images/ajax-loader.gif' id='indicator' alt='indicator' style='display: none;' />"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module InvitationsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,4 @@
|
|||
module Merb
|
||||
module NewsHelper
|
||||
end
|
||||
end
|
|
@ -0,0 +1,7 @@
|
|||
module Merb
|
||||
module PagesHelper
|
||||
def edit_page_link(page)
|
||||
"<a href='#{url(:page, :id => page.name.gsub(/ /, '_'))}' title='#{h(page.name)}'>#{h(page.name)}</a>"
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module PermissionsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module PhotoTagsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module PhotosHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
module Merb
|
||||
module SessionsHelper
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
module Merb
|
||||
module TagsHelper
|
||||
def highlight(text, phrase)
|
||||
if text.blank? || phrase.blank?
|
||||
text
|
||||
else
|
||||
match = Array(phrase).map { |p| Regexp.escape(p) }.join('|')
|
||||
text.gsub(/(#{match})/i, '<strong class="highlight">\1</strong>')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,46 @@
|
|||
class Album < ActiveRecord::Base
|
||||
validates_presence_of :name
|
||||
validates_uniqueness_of :name
|
||||
validates_format_of :name, :with => /^[\w ]+$/
|
||||
has_and_belongs_to_many :tags, :order => 'tags.name ASC'
|
||||
has_many :photos
|
||||
after_create :save_tags
|
||||
|
||||
def tag_names
|
||||
self.tags.collect { |t| t.name }.join(' ')
|
||||
end
|
||||
|
||||
def tag_names=(newtags)
|
||||
tag_name_ary = newtags.split if newtags.is_a?(String)
|
||||
tag_name_ary ||= newtags
|
||||
new_tags = []
|
||||
tag_name_ary.each do |tname|
|
||||
t = Tag.find_by_name tname
|
||||
t ||= Tag.create :name => tname
|
||||
new_tags << t
|
||||
end
|
||||
self.tags = new_tags
|
||||
end
|
||||
|
||||
def album_thumbnail
|
||||
self.photos.first
|
||||
end
|
||||
|
||||
def self.for_select
|
||||
self.find(:all, :select => 'name', :order => 'name ASC').collect do |a|
|
||||
a.name
|
||||
end
|
||||
end
|
||||
|
||||
def self.popular_tags(limit = nil)
|
||||
query = "SELECT tags.id, tags.name, count(*) AS count FROM albums_tags, tags, albums WHERE tags.id = tag_id AND albums_tags.album_id = albums.id GROUP BY tags.id, tags.name ORDER BY tags.name ASC"
|
||||
query << " LIMIT #{limit}" unless limit.nil?
|
||||
Tag.find_by_sql(query)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def save_tags
|
||||
self.tags.each { |x| x.save }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,45 @@
|
|||
require 'digest/sha1'
|
||||
|
||||
class Author < ActiveRecord::Base
|
||||
validates_uniqueness_of :name
|
||||
validates_presence_of :name
|
||||
validates_format_of :name, :with => /^\w+$/
|
||||
|
||||
attr_accessor :password, :password_confirmation
|
||||
attr_protected :encrypted_password, :salt
|
||||
|
||||
has_and_belongs_to_many :permissions
|
||||
has_many :pages
|
||||
|
||||
before_save :encrypt_password
|
||||
|
||||
def self.authenticate(username, password)
|
||||
user = self.find_by_name(username)
|
||||
return nil if user.nil?
|
||||
user.matches_password?(password) ? user : nil
|
||||
end
|
||||
|
||||
def matches_password?(cleartext_password)
|
||||
self.encrypted_password == Digest::SHA1.hexdigest("---#{cleartext_password}---#{self.salt}---")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def encrypt_password
|
||||
skip = false
|
||||
if self.password.to_s.empty? or self.password_confirmation.to_s.empty?
|
||||
if self.encrypted_password.to_s.empty?
|
||||
self.errors.add(:password, 'cannot be blank')
|
||||
else
|
||||
skip = true
|
||||
end
|
||||
elsif self.password != self.password_confirmation
|
||||
self.errors.add(:passwords, 'do not match')
|
||||
end
|
||||
return false unless self.errors.empty?
|
||||
return if skip
|
||||
self.salt = Digest::SHA1.hexdigest("---#{Time.now}---#{rand.to_s}---")
|
||||
self.encrypted_password = Digest::SHA1.hexdigest("---#{self.password}---#{self.salt}---")
|
||||
self.encrypted_password
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class Comment < ActiveRecord::Base
|
||||
belongs_to :page
|
||||
belongs_to :author
|
||||
|
||||
def name
|
||||
if self.author
|
||||
self.author.name
|
||||
else
|
||||
self.user
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
class Invitation < ActiveRecord::Base
|
||||
before_create :set_invitation_code
|
||||
validates_presence_of :recipient
|
||||
validates_format_of :recipient, :with => /^.+\@.+\.\w{2,3}$/,
|
||||
:message => 'appears to be a fake'
|
||||
attr_accessor :recipient
|
||||
|
||||
protected
|
||||
|
||||
def set_invitation_code
|
||||
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
||||
check = nil
|
||||
begin
|
||||
check = ''
|
||||
1.upto(32) { |k| check << chars[rand(chars.size - 1)] }
|
||||
end while Invitation.find_by_code(check)
|
||||
self.code = check
|
||||
end
|
||||
end
|
|
@ -0,0 +1,69 @@
|
|||
class Page < ActiveRecord::Base
|
||||
validates_format_of :name, :with => /^[\w ]+$/
|
||||
validates_uniqueness_of :name
|
||||
validates_format_of :department, :with => /^[\w]+$/, :allow_nil => true, :allow_blank => true
|
||||
|
||||
has_many :comments, :order => 'created_at ASC'
|
||||
has_and_belongs_to_many :tags, :order => 'tags.name ASC'
|
||||
belongs_to :author
|
||||
attr_protected :author_id
|
||||
has_and_belongs_to_many :pages, :join_table => 'wiki_words', :foreign_key => :source_id, :class_name => 'Page', :association_foreign_key => :destination_id
|
||||
has_and_belongs_to_many :pages_that_link_to_me, :join_table => 'wiki_words', :foreign_key => :destination_id, :association_foreign_key => :source_id, :class_name => 'Page'
|
||||
|
||||
before_create :set_author_id
|
||||
after_save :update_wiki_words
|
||||
after_save :destroy_cache
|
||||
|
||||
def self.exists?(name)
|
||||
!self.find_by_name(name).nil?
|
||||
end
|
||||
|
||||
def tag_names
|
||||
self.tags.collect { |t| t.name }.join(' ')
|
||||
end
|
||||
|
||||
def tag_names=(newtags)
|
||||
tag_name_ary = newtags.split if newtags.is_a?(String)
|
||||
tag_name_ary ||= newtags
|
||||
new_tags = []
|
||||
tag_name_ary.each do |tname|
|
||||
t = Tag.find_by_name tname
|
||||
t ||= Tag.create :name => tname
|
||||
new_tags << t
|
||||
end
|
||||
self.tags = new_tags
|
||||
end
|
||||
|
||||
def self.popular_tags(limit = nil)
|
||||
query = "SELECT tags.id, tags.name, count(*) AS count FROM pages_tags, tags, pages WHERE tags.id = tag_id AND pages_tags.page_id = pages.id GROUP BY tags.id, tags.name ORDER BY tags.name ASC"
|
||||
query << " LIMIT #{limit}" unless limit.nil?
|
||||
Tag.find_by_sql(query)
|
||||
end
|
||||
|
||||
def cache_name
|
||||
"RedCloth_#{self.id}"
|
||||
end
|
||||
|
||||
def self.wiki_word_pattern
|
||||
/\[\[([A-Za-z0-9 ]+)\]\]/
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def set_author_id
|
||||
self.author_id ||= Application.current_author_id
|
||||
end
|
||||
|
||||
def update_wiki_words
|
||||
self.pages.clear
|
||||
self.description.gsub(Page.wiki_word_pattern) do |match|
|
||||
p = Page.find_by_name($1) rescue nil
|
||||
WikiWord.create :source_id => self.id, :destination_id => p.id if p
|
||||
end
|
||||
end
|
||||
|
||||
def destroy_cache
|
||||
Cache.delete(self.cache_name)
|
||||
self.pages_that_link_to_me.each { |p| Cache.delete(p.cache_name) }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,12 @@
|
|||
class Permission < ActiveRecord::Base
|
||||
has_and_belongs_to_many :authors
|
||||
|
||||
validates_presence_of :name
|
||||
validates_uniqueness_of :name
|
||||
|
||||
def self.author_has_permission_to?(name, author = nil)
|
||||
p = self.find_by_name(name.to_s)
|
||||
p ||= self.create :name => name.to_s # auto-create permission if necessary
|
||||
p.authors.include?(author)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,97 @@
|
|||
class Photo < ActiveRecord::Base
|
||||
attr_accessor :file
|
||||
|
||||
validates_presence_of :author_id, :album_id
|
||||
|
||||
belongs_to :album
|
||||
belongs_to :author
|
||||
has_many :photo_tags, :dependent => :destroy
|
||||
has_many :tags, :through => :photo_tags
|
||||
|
||||
before_validation_on_create :set_author_id
|
||||
before_create :validate_image_sanity
|
||||
after_create :create_directories
|
||||
before_destroy :destroy_directories
|
||||
|
||||
attr_protected :author_id
|
||||
|
||||
##
|
||||
# Determines the base directory for all files in this model.
|
||||
#
|
||||
def base_directory
|
||||
"#{Merb.root}/public/photos/#{id}"
|
||||
end
|
||||
|
||||
def self.popular_tags(limit = nil)
|
||||
query = "SELECT tags.id, tags.name, count(*) AS count FROM photo_tags, tags, photos WHERE tags.id = tag_id AND photo_tags.photo_id = photos.id GROUP BY tags.id, tags.name ORDER BY tags.name ASC"
|
||||
query << " LIMIT #{limit}" unless limit.nil?
|
||||
Tag.find_by_sql(query)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
##
|
||||
# Sets the Author marker for ownership on creation.
|
||||
#
|
||||
def set_author_id
|
||||
self.author_id ||= Application.current_author_id
|
||||
end
|
||||
|
||||
##
|
||||
# Checks to make sure that the file exists and is an image.
|
||||
#
|
||||
def validate_image_sanity
|
||||
if self.file[:tempfile].nil?
|
||||
self.errors.add(:file, 'File is not a file')
|
||||
end
|
||||
if self.file[:content_type] !~ /image\/\w+/
|
||||
self.errors.add(:file, 'File is not a supported type')
|
||||
end
|
||||
if self.file[:size] > 3 * 1048576
|
||||
self.errors.add(:file, 'File is too big (3MB max)')
|
||||
end
|
||||
return false unless self.errors.empty?
|
||||
|
||||
begin
|
||||
@fstr = self.file[:tempfile].read
|
||||
iary = Magick::Image.from_blob(@fstr)
|
||||
self.filename = File.basename(self.file[:filename]).gsub(/[^\w._-]/, '')
|
||||
if iary.first.to_s =~ / (\d+)x(\d+) /
|
||||
self.width = $1
|
||||
self.height = $2
|
||||
end
|
||||
rescue
|
||||
$stderr.puts("Caught an exception saving an image:")
|
||||
$stderr.puts("* #{$!}")
|
||||
self.errors.add(:file, 'File could not be read as an image')
|
||||
return false
|
||||
end
|
||||
|
||||
self.content_type = self.file[:content_type]
|
||||
true
|
||||
end
|
||||
|
||||
##
|
||||
# Makes the directories and writes the file to disk.
|
||||
#
|
||||
def create_directories
|
||||
File.umask(0022)
|
||||
Dir.mkdir(base_directory) unless File.exist?(base_directory)
|
||||
File.open("#{base_directory}/#{self.filename}", "w") do |f|
|
||||
f.puts(@fstr)
|
||||
end
|
||||
File.chmod(0644, "#{base_directory}/#{self.filename}")
|
||||
end
|
||||
|
||||
##
|
||||
# Removes the directories and files associated with this model on destroy.
|
||||
#
|
||||
def destroy_directories
|
||||
return unless File.exists?(base_directory)
|
||||
Dir.foreach(base_directory) do |file|
|
||||
next if file =~ /^\.\.?$/
|
||||
File.delete(base_directory + '/' + file)
|
||||
end
|
||||
Dir.delete(base_directory)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
class PhotoTag < ActiveRecord::Base
|
||||
belongs_to :photo
|
||||
belongs_to :tag
|
||||
validates_presence_of :photo_id, :tag_id, :x, :y
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
class Tag < ActiveRecord::Base
|
||||
validates_format_of :name, :with => /^\w+$/
|
||||
validates_uniqueness_of :name
|
||||
|
||||
has_and_belongs_to_many :pages, :order => 'pages.name ASC'
|
||||
has_and_belongs_to_many :albums, :order => 'albums.name ASC'
|
||||
|
||||
has_many :photo_tags, :dependent => :destroy
|
||||
has_many :photos, :through => :photo_tags
|
||||
|
||||
def self.popular_tags
|
||||
tags = Page.popular_tags
|
||||
a_tags = Album.popular_tags
|
||||
p_tags = Photo.popular_tags
|
||||
|
||||
[ a_tags, p_tags ].each do |ary|
|
||||
ary.each do |tag|
|
||||
t = tags.detect { |t2| t2.name == tag.name }
|
||||
if t
|
||||
t.count = t.count.to_i + tag.count.to_i
|
||||
else
|
||||
tags << tag
|
||||
end
|
||||
end
|
||||
end
|
||||
tags.sort { |a,b| a.name <=> b.name }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
class WikiWord < ActiveRecord::Base
|
||||
end
|
|
@ -0,0 +1,34 @@
|
|||
<fieldset>
|
||||
<legend>Album Details</legend>
|
||||
<p>
|
||||
<%= text_control :name, :label => 'Name: ' %>
|
||||
</p>
|
||||
<h3>Tags</h3>
|
||||
<p>
|
||||
<p><a href="#" onclick="$('album[tag_names]').value = ''; return false;"><img src="/images/edit-clear.png" style="vertical-align: top;" /></a> <%= text_control 'tag_names', :size => 30 -%></p>
|
||||
<div id="tag_auto_complete" class="auto_complete"></div>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
||||
new Ajax.Autocompleter(
|
||||
'album_tag_names',
|
||||
'tag_auto_complete',
|
||||
'/tags/auto_complete',
|
||||
{
|
||||
paramName: 'id',
|
||||
updateElement: function(tag_name)
|
||||
{
|
||||
var new_tag = tag_name.innerHTML.gsub(/\<[^>]+\>/, '');
|
||||
var existing_tags = $('album_tag_names').value.gsub(/( |^)[^ ]+$/, '');
|
||||
var plus_space = (existing_tags.length == 0 ? '' : ' ');
|
||||
$('album_tag_names').value = existing_tags + plus_space + new_tag;
|
||||
$('album_tag_names').focus();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
//]]>
|
||||
</script>
|
|
@ -0,0 +1,12 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<a href="<%= url(:album, :id => @album.name.gsub(/ /, '_')) -%>"><img src="/images/camera-photo.png" /> Back to <%= @album.name -%></a><br />
|
||||
<% end -%>
|
||||
|
||||
<%= error_messages_for :album %>
|
||||
|
||||
<% form_for :album, :action => url(:album, :id => @album.name.gsub(/ /, '_')) do %>
|
||||
<%= partial :album_form %>
|
||||
<p>
|
||||
<%= submit_button 'Update' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,40 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if allowed_to?(:create_albums) -%><a href="<%= url(:new_album) -%>"><img src="/images/folder-new.png" alt="Create Album" /> Create An Album</a><br /><% end -%>
|
||||
<% if allowed_to?(:upload_images) -%><a href="<%= url(:new_photo) -%>"><img src="/images/emblem-photos.png" /> Upload Image</a><br /><% end %>
|
||||
<div id="tag_cloud">
|
||||
<p>Popular Tags</p>
|
||||
<%= tag_cloud @tags %>
|
||||
</div>
|
||||
<% end -%>
|
||||
|
||||
<% throw_content :for_stylesheet do -%>
|
||||
|
||||
.photo_collection {
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.photo_collection_item {
|
||||
float: right;
|
||||
width: 170px;
|
||||
min-height: 140px;
|
||||
max-height: 200px;
|
||||
margin: 5px;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
border: 1px solid #BBB;
|
||||
}
|
||||
|
||||
<% end -%>
|
||||
|
||||
<% if @albums.empty? -%>
|
||||
<p><em><strong>There were no albums found!</strong></em></p>
|
||||
<% else -%>
|
||||
<div class="photo_collection">
|
||||
<% @albums.each do |album| -%>
|
||||
<div class="photo_collection_item">
|
||||
<p><a href="<%= url(:album, :id => album.name.gsub(/ /, '_')) -%>"><%= album.name -%></a> (<%= album.photos.size -%> photos)</p>
|
||||
<% if album.album_thumbnail -%><a href="<%= url(:album, :id => album.name.gsub(/ /, '_')) -%>"><img src="<%= thumbnail_photo_url(album.album_thumbnail) -%>" /></a><% end -%>
|
||||
</div>
|
||||
<% end -%>
|
||||
</div>
|
||||
<% end -%>
|
|
@ -0,0 +1,8 @@
|
|||
<%= error_messages_for :album %>
|
||||
|
||||
<% form_for :album, :action => url(:album) do %>
|
||||
<%= partial :album_form %>
|
||||
<p>
|
||||
<%= submit_button 'Create' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,30 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if allowed_to?(:edit_album) -%><a href="<%= url(:edit_album, :id => @album.name.gsub(/ /, '_')) -%>" rel="nofollow"><img src="/images/document-save.png" /> Edit Album</a><br /><% end %>
|
||||
<% if allowed_to?(:delete_albums) -%><a href="<%= url(:delete_album, :id => @album.name.gsub(/ /, '_')) -%>" onclick="if(!confirm('Are you sure you want to delete this album?')){return false;}"><img src="/images/edit-delete.png" /> Destroy Album</a><br /><% end %>
|
||||
<% if allowed_to?(:upload_images) -%><a href="<%= url(:new_photo, :photo => { :album_id => @album.id }) -%>"><img src="/images/emblem-photos.png" /> Upload Image</a><br /><% end %>
|
||||
<% end -%>
|
||||
|
||||
<% throw_content :for_stylesheet do -%>
|
||||
|
||||
.photo {
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
<% end -%>
|
||||
|
||||
<div class="hentry">
|
||||
<h1><%= @album.name -%></h1>
|
||||
|
||||
<% @album.photos.each_with_index do |photo, idx| -%>
|
||||
<% if (idx + 1) % 3 == 1 -%><p><% end -%>
|
||||
<span class="photo"><a href="<%= url(:photo, photo) -%>" rel="nofollow" onclick="window.open(this.href);return false;"><img src="<%= thumbnail_photo_url(photo) -%>" /></a></span>
|
||||
<% if (idx + 1) % 3 == 0 or @album.photos.size == (idx + 1) -%></p><% end -%>
|
||||
<% end -%>
|
||||
|
||||
<% unless @album.tags.empty? -%>
|
||||
<br style="clear: both;" />
|
||||
<ul class="meta">
|
||||
<li>Tags: <%= @album.tags.collect { |t| "<a href='#{url(:tag, :id => t.name)}' title='#{t.name}'>#{t.name}</a>" }.join(' ') -%></li>
|
||||
</ul>
|
||||
<% end -%>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
<fieldset>
|
||||
<legend>Create an author</legend>
|
||||
<p>
|
||||
<%= text_control :name, :label => 'Name: ' %>
|
||||
</p>
|
||||
<p>
|
||||
Invitation Code: <strong><em><%= (params[:invitation_code].to_s.empty? ? 'None! This will not work!' : params[:invitation_code]) -%><%= hidden_field :name => 'invitation_code', :value => params[:invitation_code] -%></em></strong>
|
||||
</p>
|
||||
<p>
|
||||
<%= text_control :url, :label => 'Home URL: ' %>
|
||||
</p>
|
||||
<p>
|
||||
<%= password_control :password, :label => 'Password: ', :size => 40 %>
|
||||
</p>
|
||||
<p>
|
||||
<%= password_control :password_confirmation, :label => 'Password (Confirm): ', :size => 40 %>
|
||||
</p>
|
||||
</fieldset>
|
|
@ -0,0 +1,8 @@
|
|||
<%= error_messages_for :author %>
|
||||
|
||||
<% form_for :author, :action => url(:author, :id => @author.name) do -%>
|
||||
<%= partial :author_form %>
|
||||
<p>
|
||||
<%= submit_button 'Update' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,14 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if allowed_to?(:send_invitations) -%><a href="<%= url(:new_invitation) -%>"><img src="/images/mail-message-new.png" alt="Send Invitation" /> Send Invitation</a><br /><% end -%>
|
||||
<% unless logged_in? -%><a href="<%= url(:new_author) -%>"><img src="/images/contact-new.png" /> Sign up!</a><br /><% end -%>
|
||||
<% end -%>
|
||||
|
||||
<% if @authors.empty? -%>
|
||||
<p><em><strong>There were no authors found!</strong></em></p>
|
||||
<% else -%>
|
||||
<ol>
|
||||
<% @authors.each do |author| -%>
|
||||
<li><a href="<%= url(:author, :id => author.name) -%>"><%= author.name -%></a></li>
|
||||
<% end -%>
|
||||
</ol>
|
||||
<% end -%>
|
|
@ -0,0 +1,8 @@
|
|||
<%= error_messages_for :author %>
|
||||
|
||||
<% form_for :author, :action => url(:author) do %>
|
||||
<%= partial :author_form %>
|
||||
<p>
|
||||
<%= submit_button 'Create' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,8 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if @author.id == session[:author_id] or allowed_to?(:edit_author, @author) -%><a href="<%= url(:edit_author, :id => @author.name) -%>" rel="nofollow"><img src="/images/document-save.png" /> Edit Author</a><br /><% end %>
|
||||
<% if allowed_to?(:delete_authors) -%><a href="<%= url(:delete_author, :id => @author.name) -%>" onclick="if(!confirm('Are you sure you want to delete this author?')){return false;}"><img src="/images/edit-delete.png" /> Destroy Author</a><br /><% end %>
|
||||
<% unless @author.url.to_s.empty? -%><a href="<%= h(@author.url) -%>" target="new"><img src="/images/go-home.png" /> Home URL</a><br /><% end -%>
|
||||
<% if allowed_to?(:change_permissions) -%><a href="<%= url(:edit_permission, :id => @author.id) -%>"><img src="/images/preferences-system.png" /> Change Permissions</a><br /><% end %>
|
||||
<% end -%>
|
||||
|
||||
<h1><%= @author.name -%></h1>
|
|
@ -0,0 +1,21 @@
|
|||
<fieldset>
|
||||
<legend>Post a comment on <em><%= @page.name -%></em></legend>
|
||||
<%= hidden_field :name => 'page_id', :value => @page.name.gsub(/ /, '_') %>
|
||||
<% if logged_in? -%>
|
||||
<p>
|
||||
Author: <%= Author.find(session[:author_id]).name -%><%= hidden_field :name => 'comment[author_id]', :value => session[:author_id] -%>
|
||||
</p>
|
||||
<% else -%>
|
||||
<p>
|
||||
<%= text_control :user, :label => 'Name: ', :size => 32 %>
|
||||
</p>
|
||||
<% end -%>
|
||||
|
||||
<p>
|
||||
<%= text_control :url, :label => 'URL: ', :size => 60, :max_size => 256 %>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<%= text_area_control :comment, :label => 'Comment: ', :rows => 8, :cols => 60 %>
|
||||
</p>
|
||||
</fieldset>
|
|
@ -0,0 +1,12 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<a href="<%= url(:page, :id => @page.name.gsub(/ /, '_')) -%>"><img src="/images/text-html.png" alt="Return to page" /> Return to <%= @page.name -%></a><br />
|
||||
<% end -%>
|
||||
|
||||
<%= error_messages_for :comment %>
|
||||
|
||||
<% form_for :comment, :action => url(:comment) do %>
|
||||
<%= partial :comment_form %>
|
||||
<p>
|
||||
<%= submit_button 'Create' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,216 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
||||
<title><%= @exception_name %></title>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
font-family:arial;
|
||||
font-size:11px;
|
||||
}
|
||||
h1 {
|
||||
font-size:48px;
|
||||
letter-spacing:-4px;
|
||||
margin:0;
|
||||
line-height:36px;
|
||||
color:#333;
|
||||
}
|
||||
h1 sup {
|
||||
font-size: 0.5em;
|
||||
}
|
||||
h1 sup.error_500, h1 sup.error_400 {
|
||||
color:#990E05;
|
||||
}
|
||||
h1 sup.error_100, h1 sup.error_200 {
|
||||
color:#00BF10;
|
||||
}
|
||||
h1 sup.error_300 {
|
||||
/* pretty sure you cant 'see' status 300
|
||||
errors but if you could I think they
|
||||
would be blue */
|
||||
color:#1B2099;
|
||||
}
|
||||
h2 {
|
||||
font-size:36px;
|
||||
letter-spacing:-3px;
|
||||
margin:0;
|
||||
line-height:28px;
|
||||
color:#444;
|
||||
}
|
||||
a, a:visited {
|
||||
color:#00BF10;
|
||||
}
|
||||
.internalError {
|
||||
width:800px;
|
||||
margin:50px auto;
|
||||
}
|
||||
.header {
|
||||
border-bottom:10px solid #333;
|
||||
margin-bottom:1px;
|
||||
background-image: url("data:image/gif;base64,R0lGODlhAwADAIAAAP///8zMzCH5BAAAAAAALAAAAAADAAMAAAIEBHIJBQA7");
|
||||
padding:20px;
|
||||
}
|
||||
table.trace {
|
||||
width:100%;
|
||||
font-family:courier, monospace;
|
||||
letter-spacing:-1px;
|
||||
border-collapse: collapse;
|
||||
border-spacing:0;
|
||||
}
|
||||
table.trace tr td{
|
||||
padding:0;
|
||||
height:26px;
|
||||
font-size:13px;
|
||||
vertical-align:middle;
|
||||
}
|
||||
table.trace tr.file{
|
||||
border-top:2px solid #fff;
|
||||
background-color:#F3F3F3;
|
||||
}
|
||||
table.trace tr.source {
|
||||
background-color:#F8F8F8;
|
||||
display:none;
|
||||
}
|
||||
table.trace .open tr.source {
|
||||
display:table-row;
|
||||
}
|
||||
table.trace tr.file td.expand {
|
||||
width:23px;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAIAAABvSEP3AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAdVJREFUeNqMVL+TwUAYxaRIOlEhlZHGDAUzzOQ61+AqXMV1lJSU7q/QRqm8KFUcJTNn5qJkaPyoKKVz7y4mF8na5Kt29tt9+/Z97/u81+vVQ4r9frdarS6Xi7ETDIZisRjxMGPfmk4niNPpZE+xLAugbPaZ53nzvtfMBe/3+/3dbuehBrAKhZdUKkVAWa9Xsiybv0CPZDJZLr/qa5/BwgwRjYqOKIvFYjQa/aNommZh0Ww2K5UqzwfoQOPxaLPZ3FAmk0+7lplMpt1u53J5OpBOR0eZEE9wHJfP5zud93g88QhluwWbjW+5VOmKBgKBer3eaDTDYeGBQF8+x7rqIYoiPgixWJazpA6HA+MSxRArkUgMh0M409g8Ho8+9wYxxCqVSq1W26EDHGM2m4HOHQrEc38f/Yn7cLmlIRhBENzcx8cVRZnPZ/YUep2BWkjTIfA+PKVpZAXR5QxsjiqCKvGEqqp443w+0dvy17swqD0HB3S73V5PpkNg1qBqt8kwGCjmPkinM0QJbIoEa7U6UG6ToVgs4V9G2g0ESoP5Aoi7KYX5oCgf8IKbkvn9/mr1LRQKESamzgJy0g0tSZIuB3nuGqRU9Vv9C4sKkUhEkp4soxvxI8AAhWrrtXa3X8EAAAAASUVORK5CYII=);
|
||||
background-position:top left;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
table.trace .open tr.file td.expand {
|
||||
width:19px;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAB1CAIAAAAqdO2mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAXZJREFUeNrslK1ywkAUhcMOBomEOiSdqLxEBJX0NaijOsjyHGGmCGyQQYaiiiw4gktkcOmZbpsuuzQ/M5XnqJ2d3S/n3nM3rTzPLUP7/Tt0+pLcGQwG3W53OLyHzPMtjYL7q9UqSRLrD4E1Gj1orCvKYuFHUWTVkOM44/HjDcp8/lL4r6NerzeZPMm1KFw0QkDn83m5fP2lHA4fNQvRtNvtjsfDd0WzmSfb2e/fdTqdOvdh/HLJZLOn0+d2HJ+KRGzbdl23EpFlmed5cp2maRzHQq1lvQ5KMi6EUZBGfup6E1pTfd+vrGW7jbQ2C9hTt9BpqNyIWaAwAy6xg2eBz5iRC/NomiZhGN5sqmnkauo0BUGgVQoBjQ80oCACgNQdZHfTYBkF2mxCtWWAqunWpahxIDUt3QYUxIFQpJHyIWpXjinabKbbwItMHT+NyjchrP8QKaSQQgoppJBCCimkkEIKKaSQQgoppJBCCimkkEIKKaSo+hRgAEFD17X08O2NAAAAAElFTkSuQmCC);
|
||||
background-position:top left;
|
||||
background-repeat:no-repeat;
|
||||
}
|
||||
table.trace tr.source td.collapse {
|
||||
width:19px;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAB1CAIAAAAqdO2mAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAVxJREFUeNrs0zFygkAUBmBlUkgJHdABlQwVkVJKKUxBYWbkALTxMJwhltyDFkss03IF8pudIcwaDaDl/6pd2P327b7d+eHwMXs4lNkzggoVKlSoUKFChQoVKlSoUKFChQoVKlSoUKFChQqVEYqm6ft9+qiSJEkYho7jTlcw2fd9NOI4nq4gEdFwXXe1Cqco63VkWVbXRTqLhTpOwQRpF7quR1E0TgGhqvLKUFCyoQqG/rks3O6kZKW/eRFpevOCoGTXVTcMQ5EyxyDEkML1c5RzuZOICIyXqn7JBVez6282MWrx731HOv2qB8Hri2lamNk0DfpVVdV1Peodappmmua8bdvzuc7zfNprzrLMth1FnGh/X8MjCAIQv/cFz/+65PcDh7rbvYv2ZUfdj+PxsyzLgVl0hKwgTqeqKApx2LeOc7t98zyv/1FWOgvx9RPii23bmL9cetJ8Ed8CDAC6aFW8bCzFhwAAAABJRU5ErkJggg==);
|
||||
background-position:bottom left;
|
||||
background-repeat:no-repeat;
|
||||
background-color:#6F706F;
|
||||
}
|
||||
table.trace tr td.path {
|
||||
padding-left:10px;
|
||||
}
|
||||
table.trace tr td.code {
|
||||
padding-left:35px;
|
||||
white-space: pre;
|
||||
line-height:9px;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
table.trace tr td.code em {
|
||||
font-weight:bold;
|
||||
color:#00BF10;
|
||||
}
|
||||
table.trace tr td.code a {
|
||||
width: 20px;
|
||||
float: left;
|
||||
}
|
||||
table.trace tr td.code .more {
|
||||
color:#666;
|
||||
}
|
||||
table.trace tr td.line {
|
||||
width:30px;
|
||||
text-align:right;
|
||||
padding-right:4px;
|
||||
}
|
||||
.footer {
|
||||
margin-top:5px;
|
||||
font-size:11px;
|
||||
color:#444;
|
||||
text-align:right;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="internalError">
|
||||
|
||||
<div class="header">
|
||||
<h1><%= @exception_name %> <sup class="error_<%= @exception.class::STATUS %>"><%= @exception.class::STATUS %></sup></h1>
|
||||
<% if show_details = ::Merb::Config[:exception_details] -%>
|
||||
<h2><%= @exception.message %></h2>
|
||||
<% else -%>
|
||||
<h2>Sorry about that...</h2>
|
||||
<% end -%>
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<% params[:original_params].each do |param, value| %>
|
||||
<li><strong><%= param %>:</strong> <%= value.inspect %></li>
|
||||
<% end %>
|
||||
<%= "<li>None</li>" if params[:original_params].empty? %>
|
||||
</ul>
|
||||
|
||||
<h3>Session</h3>
|
||||
<ul>
|
||||
<% params[:original_session].each do |param, value| %>
|
||||
<li><strong><%= param %>:</strong> <%= value.inspect %></li>
|
||||
<% end %>
|
||||
<%= "<li>None</li>" if params[:original_session].empty? %>
|
||||
</ul>
|
||||
|
||||
<h3>Cookies</h3>
|
||||
<ul>
|
||||
<% params[:original_cookies].each do |param, value| %>
|
||||
<li><strong><%= param %>:</strong> <%= value.inspect %></li>
|
||||
<% end %>
|
||||
<%= "<li>None</li>" if params[:original_cookies].empty? %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<% if show_details %>
|
||||
<table class="trace">
|
||||
<% @exception.backtrace.each_with_index do |line, index| %>
|
||||
<tbody class="close">
|
||||
<tr class="file">
|
||||
<td class="expand">
|
||||
</td>
|
||||
<td class="path">
|
||||
<%= (line.match(/^([^:]+)/)[1] rescue 'unknown').sub(/\/((opt|usr)\/local\/lib\/(ruby\/)?(gems\/)?(1.8\/)?(gems\/)?|.+\/app\/)/, '') %>
|
||||
<% unless line.match(/\.erb:/) %>
|
||||
in "<strong><%= line.match(/:in `(.+)'$/)[1] rescue '?' %></strong>"
|
||||
<% else %>
|
||||
(<strong>ERB Template</strong>)
|
||||
<% end %>
|
||||
</td>
|
||||
<td class="line">
|
||||
<a href="txmt://open?url=file://<%=file = (line.match(/^([^:]+)/)[1] rescue 'unknown')%>&line=<%= lineno = line.match(/:([0-9]+):/)[1] rescue '?' %>"><%=lineno%></a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="source">
|
||||
<td class="collapse">
|
||||
</td>
|
||||
<td class="code" colspan="2"><% (__caller_lines__(file, lineno, 5) rescue []).each do |llineno, lcode, lcurrent| %>
|
||||
<a href="txmt://open?url=file://<%=file%>&line=<%=llineno%>"><%= llineno %></a><%='<em>' if llineno==lineno.to_i %><%= lcode.size > 90 ? CGI.escapeHTML(lcode[0..90])+'<span class="more">......</span>' : CGI.escapeHTML(lcode) %><%='</em>' if llineno==lineno.to_i %>
|
||||
<% end %>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<% end %>
|
||||
</table>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
// swop the open & closed classes
|
||||
els = document.getElementsByTagName('td');
|
||||
for(i=0; i<els.length; i++){
|
||||
if(els[i].className=='expand' || els[i].className=='collapse'){
|
||||
els[i].onclick = function(e){
|
||||
tbody = this.parentNode.parentNode;
|
||||
if(tbody.className=='open'){
|
||||
tbody.className='closed';
|
||||
}else{
|
||||
tbody.className='open';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<% end %>
|
||||
<div class="footer">
|
||||
lots of love, from <a href="#">merb</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
<p><%= params[:exception] %></p>
|
|
@ -0,0 +1 @@
|
|||
<p>The requested resource <em><strong><%= h(request.uri) -%></em></strong> could not be found.</p>
|
|
@ -0,0 +1,11 @@
|
|||
Hello,
|
||||
|
||||
You have been given an invitation to join the TuxBliki.
|
||||
Check it out at: http://penguincoder.org
|
||||
|
||||
Sign up for your account with this address:
|
||||
<%= url(:new_author, :invitation_code => @invitation.code) %>
|
||||
|
||||
Thanks,
|
||||
|
||||
The PenguinCoding Initiative
|
|
@ -0,0 +1,11 @@
|
|||
<% form_for :invitation, :action => url(:invitation) do -%>
|
||||
<fieldset>
|
||||
<legend>Invite A Drinker</legend>
|
||||
<p>
|
||||
<%= text_control 'recipient', :label => 'Recipient: ' %>
|
||||
</p>
|
||||
</fieldset>
|
||||
<p>
|
||||
<%= submit_button 'Send' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "/xhtml1-strict.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-us" lang="en-us">
|
||||
<head>
|
||||
|
||||
<title>PenguinCoder's TuxBliki<% if @page_title -%> :: <%= @page_title -%><% end -%><% if @secondary_title -%> :: <%= @secondary_title -%><% end -%></title>
|
||||
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<link rel="stylesheet" href="/stylesheets/application.css" type="text/css" media="screen" charset="utf-8" />
|
||||
|
||||
<script src="/javascripts/prototype.js" type="text/javascript"></script>
|
||||
<script src="/javascripts/scriptaculous.js" type="text/javascript"></script>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
<%= catch_content :for_stylesheet %>
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function addLoadEvent(func) {
|
||||
var oldonload = window.onload;
|
||||
if (typeof window.onload != 'function') {
|
||||
window.onload = func;
|
||||
} else {
|
||||
window.onload = function() {
|
||||
oldonload();
|
||||
func();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<%= catch_content :for_javascript %>
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<% flash.keys.each do |key| -%>
|
||||
<div id="<%= key -%>">
|
||||
<%= flash[key] %>
|
||||
</div>
|
||||
<% end -%>
|
||||
|
||||
<div id="header">
|
||||
<span style="float: left; margin: 0px 20px 0px 0px"><img src="/images/penguincoder-logo.png" /></span>
|
||||
<h1><%= @page_title or 'TuxBliki' -%></h1>
|
||||
<% if @secondary_title -%><h2><%= @secondary_title -%></h2><% end -%>
|
||||
<br style="clear: both" />
|
||||
<%
|
||||
links = []
|
||||
links << [ 'Blog', '/', 'internet-group-chat.png' ]
|
||||
links << [ 'Wiki', url(:pages), 'text-html.png' ]
|
||||
links << [ 'Post', url(:new_page), 'accessories-text-editor.png' ] if allowed_to?(:create_pages)
|
||||
links << [ 'Photo Albums', url(:albums), 'camera-photo.png' ]
|
||||
links << [ 'Authors', url(:authors), 'system-users.png' ]
|
||||
links << [ 'Tags', url(:tags), 'preferences-desktop-font.png' ]
|
||||
if logged_in?
|
||||
links << [ 'Logout', url(:delete_session, :id => session[:author_id]), 'system-log-out.png' ]
|
||||
else
|
||||
links << [ 'Login', url(:new_session), 'system-lock-screen.png' ]
|
||||
end
|
||||
links << [ 'Help', url(:page, :id => 'Help'), 'help-browser.png' ]
|
||||
-%>
|
||||
<div><%= links.collect { |l| "<a href='#{l[1]}'><img src='/images/#{l[2]}' alt='#{l[0]}' /> #{l[0]}</a>" }.join(' | ') -%></div>
|
||||
</div>
|
||||
|
||||
<div id="page">
|
||||
<div id="content">
|
||||
<%= catch_content :for_layout %>
|
||||
</div>
|
||||
<div id="sidebar">
|
||||
<%= catch_content :for_sidebar %>
|
||||
</div>
|
||||
<br style="clear: both" />
|
||||
</div>
|
||||
|
||||
<div id="footer">
|
||||
<hr />
|
||||
<p>© 2004 - 2008 penguincoder</p>
|
||||
<ul>
|
||||
<li><a href="http://merbivore.com">merb</a></li>
|
||||
<li><a href="http://quotedprintable.com/pages/scribbish">scribbish</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,54 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<div id="tag_cloud">
|
||||
<p>Popular Tags</p>
|
||||
<%= tag_cloud @tags %>
|
||||
</div>
|
||||
|
||||
<div id="things_i_do">
|
||||
<div class="title">Things I Do</div>
|
||||
<p>
|
||||
<a href="http://github.com/penguincoder"><img src="/images/utilities-terminal.png" /> Code on Github</a><br />
|
||||
<a href="http://del.icio.us/penguincoder"><img src="/images/delicious.med.gif" /> Del.icio.us Feed</a><br />
|
||||
</p>
|
||||
</div>
|
||||
<% end -%>
|
||||
|
||||
<% @secondary_title = "Demolishing innocence for #{time_lost_in_words(Time.now, @oldest_date)}" unless @oldest_date.nil? -%>
|
||||
|
||||
<% if @news.empty? -%>
|
||||
|
||||
<p><strong><em>There are no news posts, yet.</em></strong></p>
|
||||
|
||||
<% else -%>
|
||||
|
||||
<% @news.each do |page| -%>
|
||||
<%= partial 'pages/page', :with => [ page ] %>
|
||||
<% end -%>
|
||||
|
||||
<% if @page_count > 0 -%>
|
||||
<div id="pagination_links">
|
||||
|
||||
<% if @page > 0 -%>
|
||||
<a href="<%= url(:news, :page => 0) -%>"><img src="/images/go-first.png" alt="First Page" /></a> <a href="<%= url(:news, :page => 0) -%>"><img src="/images/go-previous.png" alt="Previous Page" /></a>
|
||||
<% end -%>
|
||||
|
||||
<% if @page_count > 1 -%>
|
||||
<% (@page - 4).upto(@page - 1) do |i| ; next if i < 0 -%>
|
||||
<a href="<%= url(:news, :page => i) -%>"><%= i + 1 -%></a>
|
||||
<% end %>
|
||||
|
||||
<%= @page + 1 %>
|
||||
|
||||
<% (@page + 1).upto(@page + 4) do |i| ; next if i >= @page_count -%>
|
||||
<a href="<%= url(:news, :page => i) -%>"><%= i + 1 -%></a>
|
||||
<% end %>
|
||||
|
||||
<% if @page < @page_count - 1 -%>
|
||||
<a href="<%= url(:news, :page => @page + 1) -%>"><img src="/images/go-next.png" alt="Next Page" /></a> <a href="<%= url(:news, :page => @page_count - 1) -%>"><img src="/images/go-last.png" alt="Last Page" /></a>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
||||
</div>
|
||||
<% end -%>
|
||||
|
||||
<% end -%>
|
|
@ -0,0 +1,19 @@
|
|||
<% if !@page.comments.empty? -%>
|
||||
<h3>Comments</h3>
|
||||
<ol id="comments" class="comments">
|
||||
<% @page.comments.each_with_index do |comment, position| -%>
|
||||
<li class="comment" id="comment-<%= comment.id %>">
|
||||
<span style="float: right"><% if allowed_to?(:delete_comment, comment) -%><a href="<%= url(:delete_comment, comment) -%>" onclick="if(!confirm('Are you sure you want to delete this comment?')){return false;}" rel="nofollow"><img src="/images/edit-delete.png" /></a><% end -%></span>
|
||||
|
||||
<div class="author">
|
||||
<cite><%= position + 1 -%>. <%= (comment.url.blank?) ? h(comment.name) : "<a href='#{comment.url}'>#{h(comment.name)}</a>" %></cite>
|
||||
<abbr title="<%= comment.created_at %>">said <%= time_lost_in_words comment.page.created_at, comment.created_at %> later:</abbr>
|
||||
</div>
|
||||
<div class="content">
|
||||
<%= h(comment.comment) %>
|
||||
</div>
|
||||
</li>
|
||||
<% end -%>
|
||||
</ol>
|
||||
<br />
|
||||
<% end -%>
|
|
@ -0,0 +1,21 @@
|
|||
<div class="hentry" id="page-<%= page.object_id %>">
|
||||
<h2 class="entry-title">
|
||||
<%= show_page_link(page) %>
|
||||
<span class='comment_count'><%= "#{page.comments.size} comments" unless page.comments.empty? %></span>
|
||||
</h2>
|
||||
<div class="vcard">
|
||||
Posted by <span class="fn"><%= page.author.name rescue 'AUTHOR' -%></span>
|
||||
</div>
|
||||
<abbr class="published" title="<%= page.created_at %>"><%= time_lost_in_words page.created_at %> ago<% unless page.department.to_s.empty? -%> in the <%= page.department -%> department<% end -%>.</abbr>
|
||||
<br class="clear" />
|
||||
<div class="entry-content">
|
||||
<%= show_page_description(page) %>
|
||||
</div>
|
||||
|
||||
<ul class="meta">
|
||||
<% unless page.tags.empty? -%>
|
||||
<li>Tags: <%= page.tags.collect { |t| "<a href='#{url(:tag, :id => t.name)}' title='#{t.name}'>#{t.name}</a>" }.join(' ') -%></li>
|
||||
<% end -%>
|
||||
<li>Created: <%= page.created_at -%></li>
|
||||
</ul>
|
||||
</div>
|
|
@ -0,0 +1,54 @@
|
|||
<%= error_messages_for :page %>
|
||||
|
||||
<% form_for :page, :action => url(:page, :id => @page.name.gsub(/ /, '_')) do -%>
|
||||
<fieldset>
|
||||
<legend>Update a page</legend>
|
||||
|
||||
<h3 style="margin-top: 10px;">Name</h3>
|
||||
<p><img src="/images/emblem-readonly.png" alt="Read Only" /> <span style="vertical-align: top"><%= (@page.name) %></span></p>
|
||||
|
||||
<h3>Original Author</h3>
|
||||
<p><img src="/images/emblem-readonly.png" alt="Read Only" /> <span style="vertical-align: top"><%= (@page.author.name) %></span></p>
|
||||
|
||||
<p><%= checkbox_control :published, :label => ' Published in blog?', :value => "1" %></p>
|
||||
|
||||
<h3>Department</h3>
|
||||
<p><%= text_control :department, :size => 50 %></p>
|
||||
|
||||
<h3>Description</h3>
|
||||
<p><%= text_area_control :description, :rows => 10, :cols => 70 %></p>
|
||||
|
||||
<h3>Tags</h3>
|
||||
<p>
|
||||
<p><a href="#" onclick="$('page[tag_names]').value = ''; return false;"><img src="/images/edit-clear.png" style="vertical-align: top;" /></a> <%= text_control 'tag_names', :size => 30 -%></p>
|
||||
<div id="tag_auto_complete" class="auto_complete"></div>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<br />
|
||||
|
||||
<p><%= submit_button 'Update' %></p>
|
||||
<% end -%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
||||
new Ajax.Autocompleter(
|
||||
'page_tag_names',
|
||||
'tag_auto_complete',
|
||||
'/tags/auto_complete',
|
||||
{
|
||||
paramName: 'id',
|
||||
updateElement: function(tag_name)
|
||||
{
|
||||
var new_tag = tag_name.innerHTML.gsub(/\<[^>]+\>/, '');
|
||||
var existing_tags = $('page_tag_names').value.gsub(/( |^)[^ ]+$/, '');
|
||||
var plus_space = (existing_tags.length == 0 ? '' : ' ');
|
||||
$('page_tag_names').value = existing_tags + plus_space + new_tag;
|
||||
$('page_tag_names').focus();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
//]]>
|
||||
</script>
|
|
@ -0,0 +1,16 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<div id="tag_cloud">
|
||||
<p>Popular Tags</p>
|
||||
<%= tag_cloud @tags %>
|
||||
</div>
|
||||
<% end -%>
|
||||
|
||||
<% if @pages.empty? -%>
|
||||
<p><strong><em>No pages were found!</em></strong></p>
|
||||
<% else -%>
|
||||
<ol>
|
||||
<% @pages.each do |page| -%>
|
||||
<li><%= edit_page_link page -%></li>
|
||||
<% end -%>
|
||||
</ol>
|
||||
<% end -%>
|
|
@ -0,0 +1,50 @@
|
|||
<%= error_messages_for :page %>
|
||||
|
||||
<% form_for :page, :action => url(:page) do -%>
|
||||
<fieldset>
|
||||
<legend>Create a page</legend>
|
||||
<h3 style="margin-top: 10px;">Name</h3>
|
||||
<p><%= text_control :name, :size => 50 %></p>
|
||||
|
||||
<p><%= checkbox_control :published, :label => ' Published in blog?', :value => "1" %></p>
|
||||
|
||||
<h3>Department</h3>
|
||||
<p><%= text_control :department, :size => 50 %></p>
|
||||
|
||||
<h3>Description</h3>
|
||||
<p><%= text_area_control :description, :rows => 10, :cols => 70 %></p>
|
||||
|
||||
<h3>Tags</h3>
|
||||
<p>
|
||||
<p><a href="#" onclick="$('page[tag_names]').value = ''; return false;"><img src="/images/edit-clear.png" style="vertical-align: top;" /></a> <%= text_control 'tag_names', :size => 30 -%></p>
|
||||
<div id="tag_auto_complete" class="auto_complete"></div>
|
||||
</p>
|
||||
</fieldset>
|
||||
|
||||
<br />
|
||||
|
||||
<p><%= submit_button 'Create' %></p>
|
||||
<% end -%>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
|
||||
new Ajax.Autocompleter(
|
||||
'page_tag_names',
|
||||
'tag_auto_complete',
|
||||
'/tags/auto_complete',
|
||||
{
|
||||
paramName: 'id',
|
||||
updateElement: function(tag_name)
|
||||
{
|
||||
var new_tag = tag_name.innerHTML.gsub(/\<[^>]+\>/, '');
|
||||
var existing_tags = $('page_tag_names').value.gsub(/( |^)[^ ]+$/, '');
|
||||
var plus_space = (existing_tags.length == 0 ? '' : ' ');
|
||||
$('page_tag_names').value = existing_tags + plus_space + new_tag;
|
||||
$('page_tag_names').focus();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
//]]>
|
||||
</script>
|
|
@ -0,0 +1,9 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if allowed_to?(:edit_page, @page) -%><a href="<%= url(:edit_page, :id => @page.name.gsub(/ /, '_')) -%>" rel="nofollow"><img src="/images/document-save.png" /> Edit page</a><br /><% end -%>
|
||||
<% if allowed_to?(:delete_page, @page) -%><a href="<%= url(:delete_page, :id => @page.name.gsub(/ /, '_')) -%>" onclick="if(!confirm('Are you sure you want to delete this page?')){return false;}" rel="nofollow"><img src="/images/edit-delete.png" /> Destroy page</a><br /><% end -%>
|
||||
<a href="<%= url(:controller => 'comments', :action => 'new', :page_id => @page.name.gsub(/ /, '_')) -%>" rel="nofollow"><img src="/images/mail-message-new.png" /> Post a comment</a><br />
|
||||
<% end -%>
|
||||
|
||||
<%= partial :page, :with => [ @page ] %>
|
||||
|
||||
<%= partial :comments %>
|
|
@ -0,0 +1,43 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<a href="<%= url(:author, :id => @author.name.gsub(/ /, '_')) -%>"><img src="/images/go-home.png" alt="Author's Home" /> <%= @author.name -%></a><br />
|
||||
<% end -%>
|
||||
|
||||
<script type="text/javascript">
|
||||
function check_all(form_name, field_name, checkbox_value)
|
||||
{
|
||||
if(!document.forms[form_name])
|
||||
return;
|
||||
var check_boxes = document.forms[form_name].elements[field_name];
|
||||
if(!check_boxes)
|
||||
return;
|
||||
var count_check_boxes = check_boxes.length;
|
||||
if(!count_check_boxes)
|
||||
check_boxes.checked = check_value;
|
||||
else
|
||||
// set the check value for all check boxes
|
||||
for(var i = 0; i < count_check_boxes; i++)
|
||||
check_boxes[i].checked = checkbox_value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<% form_for :permission, :action => url(:permission, @author), :id => 'permission_form' do -%>
|
||||
<%= hidden_field :name => '_method', :value => 'put' %>
|
||||
<fieldset>
|
||||
<legend>Select Author's permissions</legend>
|
||||
<p>Select: <a href="#" onclick="check_all('permission_form', 'permissions[]', true); return false">all</a> | <a href="#" onclick="check_all('permission_form', 'permissions[]', false); return false">none</a></p>
|
||||
<ul style="list-style-type: none">
|
||||
<% @permissions.each do |p| -%>
|
||||
<%
|
||||
attr = { :name => 'permissions[]', :boolean => false, :value => p.id }
|
||||
if @author.permissions.include?(p)
|
||||
attr[:checked] = true
|
||||
end
|
||||
-%>
|
||||
<li><%= checkbox_field attr -%> <%= p.name -%></li>
|
||||
<% end -%>
|
||||
</ul>
|
||||
</fieldset>
|
||||
<p>
|
||||
<%= submit_button 'Save' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,14 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<a href="<%= url(:author, :id => @author.name.gsub(/ /, '_')) -%>"><img src="/images/go-home.png" alt="Author's Home" /> <%= @author.name -%></a><br />
|
||||
<% if allowed_to?(:change_permissions) -%><a href="<%= url(:edit_permission, :id => @author.id) -%>"><img src="/images/preferences-system.png" /> Change Permissions</a><br /><% end %>
|
||||
<% end -%>
|
||||
|
||||
<% if @permissions.empty? -%>
|
||||
<p><em><strong>User has no permissions.</strong></em></p>
|
||||
<% else -%>
|
||||
<ol>
|
||||
<% @permissions.each do |p| -%>
|
||||
<li><%= p.name -%></li>
|
||||
<% end -%>
|
||||
</ol>
|
||||
<% end -%>
|
|
@ -0,0 +1,14 @@
|
|||
<h3>Tagged:</h3>
|
||||
|
||||
<p>
|
||||
<% if @photo.nil? or @photo.photo_tags.empty? -%>
|
||||
None.
|
||||
<% else -%>
|
||||
<%= @photo.photo_tags.collect { |t|
|
||||
str = "<span onmouseover=\"show_tag_at(#{t.x}, #{t.y})\" onmouseout=\"hide_tag_box()\" id=\"photo_tag_#{t.id}\">#{t.tag.name}"
|
||||
if @editable
|
||||
str += " (<a href='#' onclick='destroy_photo_tag(#{t.id}); return false;'><img src='/images/edit-delete.png' /> Remove</a>)"
|
||||
end
|
||||
str += "</span>" }.join(', ') %>
|
||||
<% end -%>
|
||||
</p>
|
|
@ -0,0 +1,17 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<a href="<%= url(:album, :id => @photo.album.name.gsub(/ /, '_')) -%>"><img src="/images/camera-photo.png" /> Back to <%= @photo.album.name -%></a><br />
|
||||
<a href="<%= url(:photo, :id => @photo.id) -%>"><img src="/images/image-x-generic.png" /> Back to photo</a><br />
|
||||
<% end -%>
|
||||
|
||||
<%= error_messages_for :photo %>
|
||||
|
||||
<% form_for :photo, :action => url(:photo, :id => @photo.id) do %>
|
||||
<fieldset>
|
||||
<legend>Change Photo Details</legend>
|
||||
<p>Photo: <img src="<%= thumbnail_photo_url(@photo) -%>" /></p>
|
||||
<p>Album: <%= select_control 'album_id', :collection => Album.for_select, :selected => (@photo.album.name rescue nil) -%></p>
|
||||
</fieldset>
|
||||
<p>
|
||||
<%= submit_button 'Update' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,17 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if @photo.album -%><a href="<%= url(:album, :id => @photo.album.name.gsub(/ /, '_')) -%>"><img src="/images/camera-photo.png" /> Back to <%= @photo.album.name -%></a><br /><% end %>
|
||||
<% end -%>
|
||||
|
||||
<%= error_messages_for :photo %>
|
||||
|
||||
<% form_for :photo, :action => url(:photo), :multipart => true, :onsubmit => "$('indicator').style.display = 'inline';" do %>
|
||||
<fieldset>
|
||||
<legend>Upload a photo</legend>
|
||||
<p>Album: <%= select_control 'album_id', :collection => Album.for_select, :selected => (@photo.album.name rescue nil) -%></p>
|
||||
<p>File: <%= file_control 'file' -%></p>
|
||||
</fieldset>
|
||||
|
||||
<p>
|
||||
<%= submit_button 'Create' %> <img src='/images/ajax-loader.gif' id='indicator' style='display:none;' />
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,231 @@
|
|||
<% throw_content :for_stylesheet do -%>
|
||||
#photo_block {
|
||||
z-index: 0;
|
||||
border: 1px solid black;
|
||||
padding: 0px;
|
||||
width: <%= @width -%>px;
|
||||
height: <%= @height -%>px;
|
||||
background-image: url('/photos/screen/<%= @photo.id -%>');
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
#photo_block_container {
|
||||
margin: 10px <%= (600 - @width) / 2 -%>px 20px <%= (600 - @width) / 2 -%>px;
|
||||
}
|
||||
#photo_tag_box {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 7px solid #6f9bdc;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: none;
|
||||
}
|
||||
#inner_photo_tag_box {
|
||||
border: 2px solid black;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
}
|
||||
#photo_tag_editor {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
<% end -%>
|
||||
|
||||
<% throw_content :for_javascript do -%>
|
||||
|
||||
function show_tag_at(x, y)
|
||||
{
|
||||
$('photo_tag_box').style.top = (y - 50) + 'px';
|
||||
$('photo_tag_box').style.left = (x - 50) + 'px';
|
||||
$('photo_tag_box').style.display = 'block';
|
||||
}
|
||||
|
||||
function hide_tag_box()
|
||||
{
|
||||
$('photo_tag_box').style.display = 'none';
|
||||
}
|
||||
|
||||
function set_coordinates(x, y)
|
||||
{
|
||||
$('cartesian_x').innerHTML = x;
|
||||
$('cartesian_y').innerHTML = y;
|
||||
$('photo_tag[x]').value = x;
|
||||
$('photo_tag[y]').value = y;
|
||||
show_tag_at(x, y);
|
||||
}
|
||||
|
||||
var block_box = true;
|
||||
function set_coordinates_from_event(event)
|
||||
{
|
||||
if(block_box)
|
||||
return;
|
||||
var xcoord = (event.offsetX ? event.offsetX : (event.pageX - $('photo_block').offsetLeft));
|
||||
var ycoord = (event.offsetY ? event.offsetY : (event.pageY - $('photo_block').offsetTop));
|
||||
if(xcoord < 0)
|
||||
xcoord = 0;
|
||||
if(xcoord > <%= @width -%>)
|
||||
xcoord = <%= @width -%>;
|
||||
if(ycoord < 0)
|
||||
ycoord = 0;
|
||||
if(ycoord > <%= @height -%>)
|
||||
ycoord = <%= @height -%>;
|
||||
set_coordinates(xcoord, ycoord);
|
||||
}
|
||||
|
||||
function update_tag_selection(tag_name)
|
||||
{
|
||||
var new_tag = tag_name.innerHTML.gsub(/\<[^>]+\>/, '');
|
||||
var existing_tags = $('tags').value.gsub(/( |^)[^ ]+$/, '');
|
||||
var plus_space = (existing_tags.length == 0 ? '' : ' ');
|
||||
$('tags').value = existing_tags + plus_space + new_tag;
|
||||
$('tags').focus();
|
||||
}
|
||||
|
||||
function photo_tag_effect()
|
||||
{
|
||||
new Effect.Highlight('photo_tags', {duration: 2.0});
|
||||
}
|
||||
|
||||
function save_new_tags()
|
||||
{
|
||||
$('save').disabled = true;
|
||||
$('indicator').show();
|
||||
|
||||
new Ajax.Updater(
|
||||
{ success: 'photo_tags', failure: 'photo_tag_errors' },
|
||||
'<%= url(:photo_tag) -%>',
|
||||
{
|
||||
parameters: Form.serialize($('photo_tag_fields')),
|
||||
asynchronous: false,
|
||||
onSuccess: function() {
|
||||
set_coordinates(0, 0);
|
||||
hide_tag_box();
|
||||
$('tags').value = '';
|
||||
photo_tag_effect();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$('indicator').hide();
|
||||
$('save').disabled = false;
|
||||
}
|
||||
|
||||
function destroy_photo_tag(tag_id)
|
||||
{
|
||||
$('indicator').show();
|
||||
new Ajax.Updater(
|
||||
{ success: 'photo_tags', failure: 'photo_tag_errors' },
|
||||
'/photo_tags/' + tag_id,
|
||||
{
|
||||
method: 'delete',
|
||||
onSuccess: function() {
|
||||
photo_tag_effect();
|
||||
},
|
||||
onComplete: function() {
|
||||
$('indicator').hide();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function toggle_photo_tag_editor(direction)
|
||||
{
|
||||
if(direction)
|
||||
{
|
||||
// swap buttons
|
||||
$('hide_photo_tag_editor').show();
|
||||
$('show_photo_tag_editor').hide();
|
||||
block_box = false;
|
||||
|
||||
// update tags to editable mode
|
||||
new Ajax.Updater(
|
||||
'photo_tags',
|
||||
'/photo_tags/<%= @photo.id -%>?editable=true',
|
||||
{
|
||||
method: 'get',
|
||||
onSuccess: function() {
|
||||
photo_tag_effect();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// transition in editor
|
||||
new Effect.BlindDown('photo_tag_editor', {duration: 1.5});
|
||||
}
|
||||
else
|
||||
{
|
||||
// toggle buttons
|
||||
$('show_photo_tag_editor').show();
|
||||
$('hide_photo_tag_editor').hide();
|
||||
block_box = true;
|
||||
|
||||
// transition out editable blocks
|
||||
new Effect.BlindUp('photo_tag_editor', {duration: 1.5});
|
||||
|
||||
// update tags to read only
|
||||
new Ajax.Updater(
|
||||
'photo_tags',
|
||||
'/photo_tags/<%= @photo.id -%>',
|
||||
{
|
||||
method: 'get',
|
||||
onSuccess: function() {
|
||||
photo_tag_effect();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
<% end -%>
|
||||
|
||||
<div id="photo_tag_editor" style="display: none;">
|
||||
<div id="photo_tag_errors" class="errorExplanation"></div>
|
||||
|
||||
<form id="photo_tag_fields" onsubmit="save_new_tags(); return false;">
|
||||
<fieldset>
|
||||
<legend>Tag a photo...</legend>
|
||||
|
||||
<%= hidden_field :name => 'photo_tag[x]', :id => 'photo_tag[x]' %>
|
||||
<%= hidden_field :name => 'photo_tag[y]', :id => 'photo_tag[y]' %>
|
||||
<%= hidden_field :name => 'photo_tag[photo_id]', :value => @photo.id %>
|
||||
|
||||
<h3 style="margin-top: 5px;">Select Tags (<span id="cartesian_x">0</span>, <span id="cartesian_y">0</span>)</h3>
|
||||
|
||||
<p><a href="#" onclick="$('tags').value = ''; return false;"><img src="/images/edit-clear.png" style="vertical-align: top;" /></a> <%= text_field :name => 'tags', :size => 30, :id => 'tags' -%> <input type="submit" value="Save" id="save" /> <img src="/images/ajax-loader.gif" style="display: none; margin-right: 5px;" id="indicator" /></p>
|
||||
<div id="photo_tag_auto_complete" class="auto_complete"></div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="photo_block_container">
|
||||
<div id="photo_block" onclick='set_coordinates_from_event(event);'>
|
||||
<div id="photo_tag_box" style="display: none;"><div id="inner_photo_tag_box"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="photo_tags">
|
||||
<%= partial 'photo_tags/photo_tags' %>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
new Ajax.Autocompleter(
|
||||
'tags',
|
||||
'photo_tag_auto_complete',
|
||||
'/tags/auto_complete',
|
||||
{
|
||||
paramName: 'id',
|
||||
updateElement: update_tag_selection
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
<% throw_content :for_sidebar do -%>
|
||||
<a href="<%= url(:album, :id => @photo.album.name.gsub(/ /, '_')) -%>"><img src="/images/camera-photo.png" /> Back to <%= @photo.album.name -%></a><br />
|
||||
<% if allowed_to?(:edit_photo, @photo) -%><a href="<%= url(:edit_photo, :id => @photo.id) -%>" rel="nofollow"><img src="/images/document-save.png" /> Edit photo</a><br /><% end %>
|
||||
<% if allowed_to?(:delete_photo, @photo) -%><a href="<%= url(:delete_photo, :id => @photo.id) -%>" onclick="if(!confirm('Are you sure you want to delete this photo?')){return false;}" rel="nofollow"><img src="/images/edit-delete.png" /> Destroy photo</a><br /><% end -%>
|
||||
<a href="<%= photo_url(@photo) -%>"><img src="/images/image-x-generic.png" /> Download original</a><br />
|
||||
<% if allowed_to?(:upload_images) -%><a href="<%= url(:new_photo, :photo => { :album_id => @photo.album_id }) -%>"><img src="/images/emblem-photos.png" /> Upload Image</a><br /><% end %>
|
||||
<% if allowed_to?(:tag_photo) -%><span id="show_photo_tag_editor"><a href="#" onclick="toggle_photo_tag_editor(true)"><img src="/images/face-monkey.png" /> Tag Image</a></span><span id="hide_photo_tag_editor" style="display: none;"><a href="#" onclick="toggle_photo_tag_editor(false); return false;"><img src="/images/face-monkey.png" /> Done Tagging</a></span><br /><% end %>
|
||||
<% end -%>
|
|
@ -0,0 +1,12 @@
|
|||
<% form_tag :action => url(:sessions) do -%>
|
||||
<fieldset>
|
||||
<legend>Login</legend>
|
||||
<p><%= text_field :name => :username, :label => 'Username: ', :id => 'username' -%></p>
|
||||
<p><%= password_field :name => :password, :label => 'Password: ' -%></p>
|
||||
</fieldset>
|
||||
<p><%= submit_button 'Login' -%></p>
|
||||
<% end -%>
|
||||
|
||||
<script type="text/javascript">
|
||||
$('username').focus();
|
||||
</script>
|
|
@ -0,0 +1,5 @@
|
|||
<ul>
|
||||
<% @tags.each do |tag| -%>
|
||||
<li><%= highlight(tag.name, @phrase) -%></li>
|
||||
<% end -%>
|
||||
</ul>
|
|
@ -0,0 +1,11 @@
|
|||
<% form_for :tag, :action => url(:tag, :id => @tag.name) do -%>
|
||||
<fieldset>
|
||||
<legend>Change a tag's name</legend>
|
||||
<p>
|
||||
<%= text_control :name, :label => 'Name: ' -%>
|
||||
</p>
|
||||
</fieldset>
|
||||
<p>
|
||||
<%= submit_button 'Save' %>
|
||||
</p>
|
||||
<% end -%>
|
|
@ -0,0 +1,8 @@
|
|||
<% if @tags.empty? -%>
|
||||
<p><em><strong>No tags were found!</strong></em></p>
|
||||
<% else -%>
|
||||
<div id="tag_cloud">
|
||||
<p>All Tags in TuxBliki</p>
|
||||
<%= tag_cloud @tags -%>
|
||||
</div>
|
||||
<% end -%>
|
|
@ -0,0 +1,18 @@
|
|||
<% throw_content :for_sidebar do -%>
|
||||
<% if allowed_to?(:edit_tags) -%><a href="<%= url(:edit_tag, :id => @tag.name) -%>"><img src="/images/document-save.png" /> Edit tag</a><br /><% end -%>
|
||||
<% if allowed_to?(:destroy_tags) -%><a href="<%= url(:delete_tag, :id => @tag.name) -%>" onclick="if(!confirm('Are you sure you want to delete this tag?')){return false;}" rel="nofollow"><img src="/images/edit-delete.png" /> Destroy tag</a><br /><% end -%>
|
||||
<% end -%>
|
||||
|
||||
<h2>Pages</h2>
|
||||
<% if @pages.empty? -%>
|
||||
<p><em><strong>None!</strong></em></p>
|
||||
<% else -%>
|
||||
<ol><%= @pages.collect { |p| "<li><a href='#{url(:page, :id => p.name.gsub(/ /, '_'))}'>#{p.name}</a></li>" }.join -%></ol>
|
||||
<% end %>
|
||||
|
||||
<h2>Albums</h2>
|
||||
<% if @albums.empty? -%>
|
||||
<p><em><strong>None!</strong></em></p>
|
||||
<% else -%>
|
||||
<ol><%= @albums.collect { |a| "<li><a href='#{url(:album, :id => a.name.gsub(/ /, '_'))}'>#{a.name}</a></li>" }.join -%></ol>
|
||||
<% end -%>
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $# -ne 1 ]] ; then
|
||||
echo Usage: $0 [username]
|
||||
exit 1
|
||||
fi
|
||||
|
||||
merb -i << EOF
|
||||
a = Author.create :name => '$1', :password => 'password', :password_confirmation => 'password'
|
||||
p = Permission.find_by_name('change_permissions')
|
||||
p ||= Permission.create :name => 'change_permissions'
|
||||
a.permissions << p
|
||||
EOF
|
|
@ -0,0 +1,76 @@
|
|||
#!/bin/bash
|
||||
# must be run from Merb.root
|
||||
merb -i << EOF
|
||||
a = Author.find :first
|
||||
|
||||
ActiveRecord::Base.establish_connection({
|
||||
:adapter => 'mysql',
|
||||
:username => 'andrew',
|
||||
:socket => '/var/lib/mysql/mysql.sock',
|
||||
:database => 'drupal'
|
||||
})
|
||||
|
||||
nodes = ActiveRecord::Base.connection.execute("SELECT * FROM node")
|
||||
comments = ActiveRecord::Base.connection.execute("SELECT * FROM comments")
|
||||
#ActiveRecord::Base.connection.execute("DELETE FROM files WHERE filename = 'thumbnail' OR filename = 'preview'")
|
||||
#files = ActiveRecord::Base.connection.execute("SELECT * FROM files")
|
||||
|
||||
ActiveRecord::Base.connection.disconnect!
|
||||
ActiveRecord::Base.establish_connection(YAML::load_file('config/database.yml')[:development])
|
||||
|
||||
pages = []
|
||||
nodes.each_hash do |node|
|
||||
next unless node['type'] == 'blog'
|
||||
c = Time.now
|
||||
c -= (c.to_i - node['created'].to_i).seconds
|
||||
[
|
||||
[ /<\/?em>/, '_' ],
|
||||
[ /<\/?strong>/, '*' ],
|
||||
[ /<blockquote>/, 'bq.' ],
|
||||
[ /<\/blockquote>/, '' ],
|
||||
[ /<\/?strike>/, '-' ],
|
||||
[ /<\/?sup>/, '^' ],
|
||||
[ /<\/?sub>/, '~' ],
|
||||
[ /<\/?pre>/, '' ],
|
||||
[ /<\/?code>/, '@' ],
|
||||
[ /<br ?\/?>/, "\n" ],
|
||||
[ /<\/?[ou]l>/, '' ],
|
||||
[ /<li>/, '* ' ],
|
||||
[ /<\/li>/, '' ],
|
||||
[ /\&\;/, '&' ]
|
||||
].each do |regexp|
|
||||
node['body'].gsub!(regexp.first, regexp.last)
|
||||
end
|
||||
node['body'].gsub!(/<a.+href=['"]([^"']+)["'].*>(.+)<\/a>/) do |match|
|
||||
"\"#{\$2}\":#{\$1}"
|
||||
end
|
||||
p = Page.new :name => node['title'].gsub(/[^A-Za-z0-9 ]/, ''), :created_at => c, :description => node['body'], :published => true, :nid => node['nid']
|
||||
p.author_id = a.id
|
||||
pages << p
|
||||
end
|
||||
|
||||
pages.each do |p|
|
||||
p.save
|
||||
if p.new_record?
|
||||
\$stderr.puts "FAILED TO SAVE PAGE #{p.name} #{p.nid}"
|
||||
p.errors.each_full { |msg| \$stderr.puts "* #{msg}" }
|
||||
next
|
||||
else
|
||||
puts "Saved page #{p.id} for node #{p.nid}"
|
||||
end
|
||||
comments.data_seek(0)
|
||||
comments.each_hash do |comment|
|
||||
next unless comment['nid'].to_i == p.nid.to_i
|
||||
c2 = Time.now
|
||||
c2 -= (c2.to_i - comment['timestamp'].to_i).seconds
|
||||
c = Comment.create(:comment => comment['comment'], :user => comment['name'], :url => comment['homepage'], :created_at => c2)
|
||||
if c.new_record?
|
||||
\$stderr.puts "FAILED TO SAVE COMMENT ON PAGE #{p.id} NODE #{p.nid}"
|
||||
c.errors.each_full { |msg| \$stderr.puts "* #{msg}" }
|
||||
else
|
||||
puts "Saved comment id #{c.id} for page #{p.id} node #{p.nid}"
|
||||
end
|
||||
end
|
||||
end.size
|
||||
|
||||
EOF
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [[ $# -ne 3 ]] ; then
|
||||
echo Usage: $0 [zipfile] [author_name] [album_name]
|
||||
exit 1
|
||||
fi
|
||||
|
||||
merb -i <<EOF
|
||||
|
||||
require 'zip/zipfilesystem'
|
||||
author = Author.find_by_name '$2'
|
||||
if author.nil?
|
||||
\$stderr.puts "Author is missing!"
|
||||
return false
|
||||
end
|
||||
album = Album.find_by_name '$3'
|
||||
if album.nil?
|
||||
\$stderr.puts "Album is missing!"
|
||||
return false
|
||||
end
|
||||
Zip::ZipFile.open('$1') do |zipfile|
|
||||
zipfile.dir.entries('.').each do |ifile_name|
|
||||
puts ifile_name
|
||||
ifile = Tempfile.new(ifile_name)
|
||||
ifile.write zipfile.file.read(ifile_name)
|
||||
ifile.rewind
|
||||
photo = Photo.new :album_id => album.id,
|
||||
:file => {
|
||||
:content_type => 'image/jpeg',
|
||||
:size => ifile.size,
|
||||
:tempfile => ifile,
|
||||
:filename => ifile_name
|
||||
}
|
||||
photo.author_id = author.id
|
||||
unless photo.save
|
||||
\$stderr.puts "PHOTO (#{ifile_name}) SAVE FAILED:"
|
||||
photo.errors.each_full { |msg| \$stderr.puts " * #{msg}" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
EOF
|
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
# This is a sample database file for the DataMapper ORM
|
||||
:development: &defaults
|
||||
:adapter: mysql
|
||||
:username: andrew
|
||||
:password:
|
||||
:socket: /var/lib/mysql/mysql.sock
|
||||
:database: tuxbliki_development
|
||||
|
||||
:test:
|
||||
<<: *defaults
|
||||
:database: tuxbliki_test
|
||||
|
||||
:production:
|
||||
<<: *defaults
|
||||
:database: tuxbliki_production
|
|
@ -0,0 +1,6 @@
|
|||
Merb.logger.info("Loaded DEVELOPMENT Environment...")
|
||||
Merb::Config.use { |c|
|
||||
c[:exception_details] = true
|
||||
c[:reload_classes] = true
|
||||
c[:reload_time] = 0.5
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
Merb.logger.info("Loaded PRODUCTION Environment...")
|
||||
Merb::Config.use { |c|
|
||||
c[:exception_details] = false
|
||||
c[:reload_classes] = false
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
Merb.logger.info("Loaded TEST Environment...")
|
||||
Merb::Config.use { |c|
|
||||
c[:exception_details] = true
|
||||
c[:reload_classes] = true
|
||||
c[:reload_time] = 0.5
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
Gem.clear_paths
|
||||
Gem.path.unshift(Merb.root / "gems")
|
||||
$LOAD_PATH.unshift(Merb.root / "lib")
|
||||
|
||||
Merb::Config.use do |c|
|
||||
c[:session_secret_key] = '9e6d92dd24c39be48946fc947255476fa4d7f7e9'
|
||||
c[:session_store] = :activerecord
|
||||
end
|
||||
|
||||
use_orm :activerecord
|
||||
use_test :rspec
|
||||
|
||||
dependencies 'merb_helpers', 'merb_has_flash', 'merb-mailer'
|
||||
require 'redcloth'
|
||||
require 'RMagick'
|
||||
require 'memcache'
|
||||
require 'memcache_util'
|
||||
|
||||
Merb::BootLoader.after_app_loads do
|
||||
config_path = File.join(Merb.root, 'config', 'memcache.yml')
|
||||
if File.file?(config_path) and File.readable?(config_path)
|
||||
memcache_connection_str = YAML.load(File.read(config_path))
|
||||
else
|
||||
memcache_connection_str = 'localhost:11211'
|
||||
end
|
||||
CACHE = MemCache.new memcache_connection_str
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
localhost:11211
|
|
@ -0,0 +1 @@
|
|||
run Merb::Rack::Application.new
|
|
@ -0,0 +1,34 @@
|
|||
Merb.logger.info("Compiling routes...")
|
||||
Merb::Router.prepare do |r|
|
||||
r.match('/node/:id').to(
|
||||
:controller => 'node',
|
||||
:action => 'show'
|
||||
)
|
||||
r.resources :pages
|
||||
r.resources :comments
|
||||
r.resources :tags
|
||||
r.match('/tags/auto_complete').to(
|
||||
:controller => 'tags',
|
||||
:action => 'auto_complete'
|
||||
)
|
||||
r.resources :authors
|
||||
r.resources :sessions
|
||||
r.resources :permissions
|
||||
r.resources :news
|
||||
r.resources :invitations
|
||||
r.resources :albums
|
||||
r.resources :photos
|
||||
r.match('/photos/thumbnail/:id').to(
|
||||
:controller => 'photos',
|
||||
:action => 'thumbnail'
|
||||
)
|
||||
r.match('/photos/screen/:id').to(
|
||||
:controller => 'photos',
|
||||
:action => 'screen'
|
||||
)
|
||||
r.resources :photo_tags
|
||||
r.match('/').to(
|
||||
:controller => 'news',
|
||||
:action => 'index'
|
||||
)
|
||||
end
|
After Width: | Height: | Size: 574 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 864 B |
After Width: | Height: | Size: 628 B |
After Width: | Height: | Size: 873 B |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 773 B |
After Width: | Height: | Size: 680 B |
After Width: | Height: | Size: 644 B |
After Width: | Height: | Size: 430 B |
After Width: | Height: | Size: 518 B |
After Width: | Height: | Size: 784 B |
After Width: | Height: | Size: 635 B |
After Width: | Height: | Size: 666 B |
After Width: | Height: | Size: 606 B |