Donnerstag, 22. Mai 2008

Traps falls installing things, addons and packages

It turns out that using preconfigured binaries and packages are waste of time.
For example. i install ruby using:

useraccount> pfexec pkg install ruby-dev

The package was compiled on the SUN cc compiler - which is fine, but.....
the setup.rb file of the ruby system has all the environment variables set from the machine it was compiled on - and not mine. Editing that file by hand to adapt the environment to my machine is a night mare.

The RMagick gem and for that matter the source code both look at the environment in the setup.rb file and because nothing in there is relevant to my machine the install fails.

useraccount> pfexec uninstall ruby-dev
useraccount> su
superuseraccount> pfexec rm -r /ruby

So the only way to do this properly is uninstall the ruby pkg, get rid of the installation from my file system, down load the source and compile it again.

useraccount> cd /export/home/tmp
useraccount>pfexec wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.6-p110.tar.bz2
useraccount>pfexec bunzip2 -dc ruby-1.8.6-p110.tar.bz2 | tar xf -

Using ruby setup.rb

This is a great place to read about it

Mittwoch, 21. Mai 2008

Setting up sendmail

according to the man pages sendmail does not let you send mails outside your domain unless you allow it to.

useraccount> svccfg -s svc:/network/smtp:sendmail setprop config/local_only = false
useraccount> svcadm refresh svc:/network/smtp:sendmail
useraccount> svcadm restart svc:/network/smtp:sendmail

testit

useraccount> sendmail someone@domain.com

Dienstag, 20. Mai 2008

Installing RMagick and ImageMagick

OK this took a day to find out.
RMagick wraps around ImageMagick so you need both of them.
To install ImageMagic you need perl - which is fine but you won't be able to install (configure and make) if perl has been compiled with a c compiler from sun. It throws out -KPIC for gcc and it should send gcc a -fPIC when compiling.

So move rename perl link in the /usr/bin and the the perl root directory wherever that might be forexample /perl

get the stable perl source code from perl.com and download it
useraccount> pfexec tar xvf perl_download
useraccount> pfexec perl_download
useraccount> pfexec ./Configure
useraccount> pfexec make
useraccount> pfexec make test
useraccount> pfexec make install

perl should now be in /opt/bin/perl with a link to it from /usr/bin

Once you have done that download ImageMagick source files
useraccount> pfexec tar xvf ImageMagick
useraccount> cd ImageMagick
useraccount> pfexec ./configure --disable-static --with-modules --without-perl --without-magick-plus-plus --with-quantum-depth=8 CC=gcc
useraccount> pfexec make
useraccount> pfexec make install

ImageMagick should now be in /usr/local/bin

Then test it with
useraccount> /usr/local/bin/convert logo: logo.gif

I did most of the above based on the info here and here

Installing will_pagenate

useraccount> pfexec gem install mislav-will_paginate --source http://gems.github.com/

manual

install plugin acts_as_taggable_on_steroids

ruby script/plugin install http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids

== Instructions

This plugin is based on acts_as_taggable by DHH but includes extras
such as tests, smarter tag assignment, and tag cloud calculations.

== Installation

ruby script/plugin install http://svn.viney.net.nz/things/rails/plugins/acts_as_taggable_on_steroids

== Usage

=== Prepare database

Generate and apply the migration:

ruby script/generate acts_as_taggable_migration
rake db:migrate

=== Basic tagging

Let's suppose users have many posts and we want those posts to have tags.
The first step is to add +acts_as_taggable+ to the Post class:

class Post < ActiveRecord::Base
acts_as_taggable

belongs_to :user
end

We can now use the tagging methods provided by acts_as_taggable, #tag_list and #tag_list=. Both these
methods work like regular attribute accessors.

p = Post.find(:first)
p.tag_list # []
p.tag_list = "Funny, Silly"
p.save
p.tag_list # ["Funny", "Silly"]

You can also add or remove arrays of tags.

p.tag_list.add("Great", "Awful")
p.tag_list.remove("Funny")

=== Finding tagged objects

To retrieve objects tagged with a certain tag, use find_tagged_with.

Post.find_tagged_with('Funny, Silly')

By default, find_tagged_with will find objects that have any of the given tags. To
find only objects that are tagged with all the given tags, use match_all.

Post.find_tagged_with('Funny, Silly', :match_all => true)

See ActiveRecord::Acts::Taggable::InstanceMethods for more methods and options.

=== Tag cloud calculations

To construct tag clouds, the frequency of each tag needs to be calculated.
Because we specified +acts_as_taggable+ on the Post class, we can
get a calculation of all the tag counts by using Post.tag_counts. But what if we wanted a tag count for
an single user's posts? To achieve this we call tag_counts on the association:

User.find(:first).posts.tag_counts

A helper is included to assist with generating tag clouds. Include it in your helper file:

module ApplicationHelper
include TagsHelper
end

You can also use the counts method on Tag to get the counts for all tags in the database.

Tag.counts

Here is an example that generates a tag cloud.

Controller:

class PostController < ApplicationController
def tag_cloud
@tags = Post.tag_counts
end
end

View:
<% tag_cloud @tags, %w(css1 css2 css3 css4) do |tag, css_class| %>
<%= link_to tag.name, { :action => :tag, :id => tag.name }, :class => css_class %>
<% end %>

CSS:

.css1 { font-size: 1.0em; }
.css2 { font-size: 1.2em; }
.css3 { font-size: 1.4em; }
.css4 { font-size: 1.6em; }

=== Caching

It is useful to cache the list of tags to reduce the number of queries executed. To do this,
add a column named cached_tag_list to the model which is being tagged. The column should be long enough to hold
the full tag list and must have a default value of null, not an empty string.

class CachePostTagList < ActiveRecord::Migration
def self.up
add_column :posts, :cached_tag_list, :string
end
end

class Post < ActiveRecord::Base
acts_as_taggable

# The caching column defaults to cached_tag_list, but can be changed:
#
# set_cached_tag_list_column_name "my_caching_column_name"
end

The details of the caching are handled for you. Just continue to use the tag_list accessor as you normally would.
Note that the cached tag list will not be updated if you directly create Tagging objects or manually append to the
tags or taggings associations. To update the cached tag list you should call save_cached_tag_list manually.

=== Delimiter

If you want to change the delimiter used to parse and present tags, set TagList.delimiter.
For example, to use spaces instead of commas, add the following to config/environment.rb:

TagList.delimiter = " "

=== Unused tags

Set Tag.destroy_unused to remove tags when they are no longer being
used to tag any objects. Defaults to false.

Tag.destroy_unused = true

#######################################

IMPORTANT: If you are using join table habtm then you can add

:conditions => {} for example to somthing like p = Post.find(:first)

i.e.

p = Post.find(:first) :conditions => {user.id => current_user }

this will allow you to set or access only the tags for a specific user is a situation where you might have a habtm user picture relationship where a user can add tags to thier pictures.

Install plugin attachement_fu

ruby script/plugin install attachment_fu

create a scaffold
=============
ruby script/generate scaffold Photo parent_id:integer content_type:string filename:string size:integer width:integer height:integer

photo migration
=============

class CreatePhotos < default =""> ""
t.string :content_type, :default => ""
t.string :filename, :default => ""
t.integer :size, :default => 0
t.integer :width, :default => 0
t.integer :height, :default => 0

t.timestamps
end
photo=Photo.new(:content_type=>" image/jpeg", :filename=>"default_avatar_1.jpg", :size => 4.kilobytes, :width=>114, :height=>150)
photo.save
photo=Photo.new(:parent_id => photo.id, :content_type=>" image/jpeg", :filename=>"default_avatar_1_thumb.jpg", :thumbnail => "thumb", :size => 4.kilobytes, :width=>24, :height=>32)
photo.save
end

def self.down
drop_table :photos
end
end

photo.rb
=======

class Photo < ActiveRecord::Base
has_one :profile

has_attachment :content_type => :image,
:storage => :file_system,
:size => 1.kilobyte..20.kilobytes,
:resize_to => '150x150'
# :thumbnails => { :thumb => '32x32' }

# validates_numericality_of :size, :only_integer => true, :greater_than => 1.kilobyte, :less_than => 20.kilobytes, :message => "File size out of range"
#TODO get the regex for content type
#validates_format_of :content_type, :with => :image, :message => "Picture is not an image"
validates_presence_of :width, :on => :update, :message => "width missing"
validates_presence_of :height, :on => :update, :messgae => "height missing"
validates_presence_of :filename, :on => :update, :message => "File name missing"

#attr_accessible :filename, :content_type, :width, :height, :size

end

###########################################################################

attachment-fu
=============

attachment_fu is a plugin by Rick Olson (aka technoweenie ) and is the successor to acts_as_attachment. To get a basic run-through of its capabilities, check out Mike Clark's tutorial .


attachment_fu functionality
===========================

attachment_fu facilitates file uploads in Ruby on Rails. There are a few storage options for the actual file data, but the plugin always at a minimum stores metadata for each file in the database.

There are three storage options for files uploaded through attachment_fu:
File system
Database file
Amazon S3

Each method of storage many options associated with it that will be covered in the following section. Something to note, however, is that the Amazon S3 storage requires you to modify config/amazon_s3.yml and the Database file storage requires an extra table.


attachment_fu models
====================

For all three of these storage options a table of metadata is required. This table will contain information about the file (hence the 'meta') and its location. This table has no restrictions on naming, unlike the extra table required for database storage, which must have a table name of db_files (and by convention a model of DbFile).

In the model there are two methods made available by this plugins: has_attachment and validates_as_attachment.

has_attachment(options = {})
This method accepts the options in a hash:
:content_type # Allowed content types.
# Allows all by default. Use :image to allow all standard image types.
:min_size # Minimum size allowed.
# 1 byte is the default.
:max_size # Maximum size allowed.
# 1.megabyte is the default.
:size # Range of sizes allowed.
# (1..1.megabyte) is the default. This overrides the :min_size and :max_size options.
:resize_to # Used by RMagick to resize images.
# Pass either an array of width/height, or a geometry string.
:thumbnails # Specifies a set of thumbnails to generate.
# This accepts a hash of filename suffixes and RMagick resizing options.
# This option need only be included if you want thumbnailing.
:thumbnail_class # Set which model class to use for thumbnails.
# This current attachment class is used by default.
:path_prefix # path to store the uploaded files.
# Uses public/#{table_name} by default for the filesystem, and just #{table_name} for the S3 backend.
# Setting this sets the :storage to :file_system.
:storage # Specifies the storage system to use..
# Defaults to :db_file. Options are :file_system, :db_file, and :s3.
:processor # Sets the image processor to use for resizing of the attached image.
# Options include ImageScience, Rmagick, and MiniMagick. Default is whatever is installed.


Examples:
has_attachment :max_size => 1.kilobyte
has_attachment :size => 1.megabyte..2.megabytes
has_attachment :content_type => 'application/pdf'
has_attachment :content_type => ['application/pdf', 'application/msword', 'text/plain']
has_attachment :content_type => :image, :resize_to => [50,50]
has_attachment :content_type => ['application/pdf', :image], :resize_to => 'x50'
has_attachment :thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
has_attachment :storage => :file_system, :path_prefix => 'public/files'
has_attachment :storage => :file_system, :path_prefix => 'public/files',
:content_type => :image, :resize_to => [50,50]
has_attachment :storage => :file_system, :path_prefix => 'public/files',
:thumbnails => { :thumb => [50, 50], :geometry => 'x50' }
has_attachment :storage => :s3

validates_as_attachment
This method prevents files outside of the valid range (:min_size to :max_size, or the :size range) from being saved. It does not however, halt the upload of such files. They will be uploaded into memory regardless of size before validation.

Example:
validates_as_attachment


attachment_fu migrations
========================

Fields for attachment_fu metadata tables...
in general:
size, :integer # file size in bytes
content_type, :string # mime type, ex: application/mp3
filename, :string # sanitized filename
that reference images:
height, :integer # in pixels
width, :integer # in pixels
that reference images that will be thumbnailed:
parent_id, :integer # id of parent image (on the same table, a self-referencing foreign-key).
# Only populated if the current object is a thumbnail.
thumbnail, :string # the 'type' of thumbnail this attachment record describes.
# Only populated if the current object is a thumbnail.
# Usage:
# [ In Model 'Avatar' ]
# has_attachment :content_type => :image,
# :storage => :file_system,
# :max_size => 500.kilobytes,
# :resize_to => '320x200>',
# :thumbnails => { :small => '10x10>',
# :thumb => '100x100>' }
# [ Elsewhere ]
# @user.avatar.thumbnails.first.thumbnail #=> 'small'
that reference files stored in the database (:db_file):
db_file_id, :integer # id of the file in the database (foreign key)

Field for attachment_fu db_files table:
data, :binary # binary file data, for use in database file storage


attachment_fu views
===================

There are two main views tasks that will be directly affected by attachment_fu: upload forms and displaying uploaded images.

There are two parts of the upload form that differ from typical usage.
1. Include ':multipart => true' in the html options of the form_for tag.
Example:
<% form_for(:attachment_metadata, :url => { :action => "create" }, :html => { :multipart => true }) do |form| %>

2. Use the file_field helper with :uploaded_data as the field name.
Example:
<%= form.file_field :uploaded_data %>

Displaying uploaded images is made easy by the public_filename method of the ActiveRecord attachment objects using file system and s3 storage.

public_filename(thumbnail = nil)
Returns the public path to the file. If a thumbnail prefix is specified it will return the public file path to the corresponding thumbnail.
Examples:
attachment_obj.public_filename #=> /attachments/2/file.jpg
attachment_obj.public_filename(:thumb) #=> /attachments/2/file_thumb.jpg
attachment_obj.public_filename(:small) #=> /attachments/2/file_small.jpg

When serving files from database storage, doing more than simply downloading the file is beyond the scope of this document.


attachment_fu controllers
=========================

There are two considerations to take into account when using attachment_fu in controllers.

The first is when the files have no publicly accessible path and need to be downloaded through an action.

Example:
def readme
send_file '/path/to/readme.txt', :type => 'plain/text', :disposition => 'inline'
end

See the possible values for send_file for reference.


The second is when saving the file when submitted from a form.
Example in view:
<%= form.file_field :attachable, :uploaded_data %>

Example in controller:
def create
@attachable_file = AttachmentMetadataModel.new(params[:attachable])
if @attachable_file.save
flash[:notice] = 'Attachment was successfully created.'
redirect_to attachable_url(@attachable_file)
else
render :action => :new
end
end

install plugin restfull_authentication

script/plugin source http://svn.techno-weenie.net/projects/plugins
script/plugin/install restful_authentication

script/generate authenticated user sessions

To use:

./script/generate authenticated user sessions --include-activation

The first parameter specifies the model that gets created in signup(typically a user or account model). A model with migration is created, as well as a basic controller with the create method.

The second parameter specifies the sessions controller name. This is the controller that handles the actual login/logout function on the
site.

The third parameter (--include-activation) generates the code for a ActionMailer and its respective Activation Code through email.

You can pass --skip-migration to skip the user migration.

Also, add an observer to config/environment.rb if you chose the --include-activation option

config.active_record.observers = :user_observer # or whatever you named your model

SVN Helpful links

http://www.yasashiisyndicate.org/wp-content/uploads/2006/05/subversion.html

Using Rails with SVN

1. mkdir getready
2. cd getready
3. rails projectname
4. mv projectname trunk
5. mkdir tags
6. mkdir branches
7. cd trunk/config
8. mv database.yml database_example.yml
9. cd ..
10. rm -r tmp/*
11. rm -r log/*
12. cd ..
13 svn import . http://path_to_repository -m "initial import"
14. ...now you can get rid of getready folder - we dont need it anymore
15. svn co http://path_to_project_trunk projectname
16. cd projectname
17. cp config/database_example.yml database.yml
18. add passwords to the database entries
19. svn propset svn:ignore database.yml config/
20. svn propset svn:ignore "*" tmp/
21. svn propset svn:ignore "*" logs/
22. svn commit -m "ignoring files"
23. svn copy http://from_repository_trunk http://repository_tag_path_REL_XXX -m "initial snapshot release"

############################
# just a few things to remember
############################

1. when generating a model, controller or scaffold use the following

useraccount>ruby script/generate scaffold angry farmer bales_of_hey:integer name -c

DON'T FORGET THE -c AT THE END!!!

2. When installing a plugin

ruby script/install name_of_plugin -x

also a great railscast on the basics.

Working

To see the status of the files in the repository use:

useraccount> svn status

To commit changes to the files

useraccount> svn commit -m "somthing about what you are commiting"

To add files that you have changes (they have a ? next to them when you see the status).

useraccount> svn add directory_and_name_of_file

to ignore files

useraccount> svn propset svn:ignore *.pyc dirname
or
useraccount> svn propset svn:ignore dirname

setting up svn with a rails 2.0.2 project

more or less got this from here.

Go to the directory you want to set up the rails project in.

then

useraccount> mkdir svn_setup
useraccount> cd svn_setup
useraccount> rails project_name -d mysql
useraccount> mv project_name trunk
useraccount> mkdir tags
useraccount> mkdir branches
useraccount> cd trunk
useraccount> rm -r tmp/*
useraccount> rm -r log/*
useraccount> mv config/database.yml database_example.yml
useraccount> cd ..
useraccount> svn import . url_of_svn_repository_space_on_assembla -m "initial repository import" --user name_of_assembla_user

now the project should be in the svn repository in assembla

now checkout the project from the repository in assembla to your localhost

useraccount> cd
useraccount> svn co url_of_svn_repository_space_on_assembla/trunk project_name

project_name is now what you can work on and thus you can get rid of the svn_setup folder you made earlier.

useraccount> rm -r svn_setup

now for the last bits and bobs.

useraccount> cd project_name
useraccount> cp /config/database_example.yml database.yml

useraccount> svn propset svn:ignore database.yml config/
useraccount> svn propset svn:ignore "*" log/
useraccount> svn propset svn:ignore "*" tmp/

Installing svn repository space on assembla

I would rather emulate what really might happen with a proper svn than use my local file system for a svn repository so sign up to assembla.com and get some svn space.

under the tab 'Trac/SVN' you will get the url of the SVN repository space.

Setting up mysql

go to the user and groups setting in the gnome system administration menu and set the mysql user password to something that makes sense for you. Then give the mysql user a shell '/bin/bash' (setting in the advanced tab of user and groups) and then close all the windows with ok to set the changes.

Then change to user mysql

useraccount>su - mysql
password:

and enter the mysql password

now you should have the bash promt:

#bash>

then enter

#bash>mysql_install_db

then

#bash>mysqld --skip-grant-tables &

then

#bash>mysql

you should get the mysql promt

mysql>UPDATE mysql.user SET Password=PASSWORD('MyNewPass') WHERE User='root';

mysql> FLUSH PRIVILEGES;

############################
############################

now open a new terminal window....

useraccount> pfexec /usr/bin/svcadm enable database/mysql:version_50

this should start the mysql database (pfexec /usr/bin/svcadm disable database/mysql:version_50 stops the database)

if you want mysql to automatically start and stop with powerup and powerdown

then do this (which i have not)

pfexec /usr/sbin/svccfg import /var/svc/manifest/application/database/mysql.xml


DO NOT install AMP developers environment

Installing the reconfigured AMP environment for opensolaris caused me a lot of problems: machine not shutting down properly. not being able to shutdown via GNOME, not unmount startd properly and not getting any Internet when the machine boots up after a shutdown, which is not a shutdown but a restart instead.

Installing Mysql

as a normal user

useraccount>pexec pkg install SUNWmysql5

This installs mysql in /usr/mysql

Then change to su root and change the owner and groups of the files in etc and var as follows.

root>chown -R mysql:mysql /etc/mysql
root>chown -R mysql:mysql /var/mysql

also see docs

Installing Rails

as normal user (gems was installed with ruby).

useraccount>pfexec gem install rails --include-dependencies

Rails should now be in /usr/ruby/1.8

installing Ruby

Do as normal user account.

useraccount> pfexec pkg install ruby-dev

ruby should now be in /usr/ruby