[Logilogi-svn] SF.net SVN: logilogi: [283] projects
Status: Beta
Brought to you by:
wybow
|
From: <wy...@us...> - 2007-05-20 09:51:14
|
Revision: 283
http://logilogi.svn.sourceforge.net/logilogi/?rev=283&view=rev
Author: wybow
Date: 2007-05-20 02:51:03 -0700 (Sun, 20 May 2007)
Log Message:
-----------
Initial import of side-project ogog.org
Added Paths:
-----------
projects/
projects/ogog/
projects/ogog/README
projects/ogog/Rakefile
projects/ogog/app/
projects/ogog/app/controllers/
projects/ogog/app/controllers/account_controller.rb
projects/ogog/app/controllers/application.rb
projects/ogog/app/controllers/doc_controller.rb
projects/ogog/app/controllers/download_controller.rb
projects/ogog/app/controllers/feed_controller.rb
projects/ogog/app/controllers/post_controller.rb
projects/ogog/app/controllers/user_controller.rb
projects/ogog/app/helpers/
projects/ogog/app/helpers/application_helper.rb
projects/ogog/app/helpers/feed_helper.rb
projects/ogog/app/helpers/post_helper.rb
projects/ogog/app/helpers/user_helper.rb
projects/ogog/app/models/
projects/ogog/app/models/context.rb
projects/ogog/app/models/feed.rb
projects/ogog/app/models/link.rb
projects/ogog/app/models/membership.rb
projects/ogog/app/models/post.rb
projects/ogog/app/models/tag.rb
projects/ogog/app/models/tagging.rb
projects/ogog/app/models/user.rb
projects/ogog/app/models/vote.rb
projects/ogog/app/views/
projects/ogog/app/views/account/
projects/ogog/app/views/account/_login.rhtml
projects/ogog/app/views/account/forgot.rhtml
projects/ogog/app/views/account/login.rhtml
projects/ogog/app/views/account/signup.rhtml
projects/ogog/app/views/doc/
projects/ogog/app/views/doc/_slide.rhtml
projects/ogog/app/views/doc/api.rhtml
projects/ogog/app/views/doc/tour.rhtml
projects/ogog/app/views/feed/
projects/ogog/app/views/feed/_last_post.rhtml
projects/ogog/app/views/feed/_last_posts.rhtml
projects/ogog/app/views/feed/claim.rhtml
projects/ogog/app/views/feed/new.rhtml
projects/ogog/app/views/feed/show.rhtml
projects/ogog/app/views/layouts/
projects/ogog/app/views/layouts/main.rhtml
projects/ogog/app/views/post/
projects/ogog/app/views/post/_cloud.rhtml
projects/ogog/app/views/post/_double_url_bar.rhtml
projects/ogog/app/views/post/_post.rhtml
projects/ogog/app/views/post/_post_top_block_score.rhtml
projects/ogog/app/views/post/_posts.rhtml
projects/ogog/app/views/post/_rating_bar.rhtml
projects/ogog/app/views/post/_viewpoints.rhtml
projects/ogog/app/views/post/index.rhtml
projects/ogog/app/views/post/rate.rjs
projects/ogog/app/views/post/viewpoint.rhtml
projects/ogog/app/views/shared/
projects/ogog/app/views/shared/_menu.rhtml
projects/ogog/app/views/shared/_single_url_bar.rhtml
projects/ogog/app/views/shared/_sponsoring.rhtml
projects/ogog/app/views/user/
projects/ogog/app/views/user/_badge.rhtml
projects/ogog/app/views/user/_badges.rhtml
projects/ogog/app/views/user/badge.rhtml
projects/ogog/app/views/user/new.rhtml
projects/ogog/app/views/user/show.rhtml
projects/ogog/components/
projects/ogog/config/
projects/ogog/config/boot.rb
projects/ogog/config/daemons.yml
projects/ogog/config/database.yml.tmpl
projects/ogog/config/environment.rb.tmpl
projects/ogog/config/environments/
projects/ogog/config/environments/development.rb
projects/ogog/config/environments/production.rb
projects/ogog/config/environments/test.rb
projects/ogog/config/routes.rb
projects/ogog/db/
projects/ogog/db/migrate/
projects/ogog/db/migrate/001_initial_schema.rb
projects/ogog/db/schema.rb
projects/ogog/doc/
projects/ogog/doc/CONTRIBUTORS.txt
projects/ogog/doc/LICENSE.txt
projects/ogog/doc/README_FOR_APP
projects/ogog/lib/
projects/ogog/lib/daemons/
projects/ogog/lib/daemons/feedharvester.rb
projects/ogog/lib/daemons/ranking.rb
projects/ogog/lib/daemons/ranking_ctl
projects/ogog/lib/extensions/
projects/ogog/lib/extensions/active_support.rb
projects/ogog/lib/extensions/array.rb
projects/ogog/lib/extensions/cgi.rb
projects/ogog/lib/extensions/fixnum.rb
projects/ogog/lib/extensions/float.rb
projects/ogog/lib/extensions/module.rb
projects/ogog/lib/extensions/nil_class.rb
projects/ogog/lib/extensions/tabular_form_builder.rb
projects/ogog/lib/extensions.rb
projects/ogog/lib/modules/
projects/ogog/lib/modules/body_builder_module.rb
projects/ogog/lib/task_helper.rb
projects/ogog/lib/tasks/
projects/ogog/lib/tasks/commit.rake
projects/ogog/lib/tasks/do_check_commit.rake
projects/ogog/lib/tasks/do_commit.rake
projects/ogog/lib/tasks/do_dev_db.rake
projects/ogog/lib/tasks/do_docs.rake
projects/ogog/lib/tasks/do_update.rake
projects/ogog/lib/tasks/redo_dev_db.rake
projects/ogog/log/
projects/ogog/public/
projects/ogog/public/.htaccess
projects/ogog/public/404.html
projects/ogog/public/500.html
projects/ogog/public/dispatch.cgi
projects/ogog/public/dispatch.fcgi
projects/ogog/public/dispatch.rb
projects/ogog/public/favicon.ico
projects/ogog/public/images/
projects/ogog/public/images/badge-logo.png
projects/ogog/public/images/badge-logo.svg
projects/ogog/public/images/bar.jpg
projects/ogog/public/images/bar.svg
projects/ogog/public/images/feed.png
projects/ogog/public/images/logo.jpg
projects/ogog/public/images/logo.svg
projects/ogog/public/images/rails.png
projects/ogog/public/images/req_rec.png
projects/ogog/public/images/req_rec.svg
projects/ogog/public/images/skull.png
projects/ogog/public/images/skull.svg
projects/ogog/public/images/skulls.jpg
projects/ogog/public/images/skulls.svg
projects/ogog/public/images/star.png
projects/ogog/public/images/star.svg
projects/ogog/public/images/stars.jpg
projects/ogog/public/images/stars.svg
projects/ogog/public/images/tour/
projects/ogog/public/images/tour/0.png
projects/ogog/public/images/tour/0.svg
projects/ogog/public/images/tour/1.png
projects/ogog/public/images/tour/1.svg
projects/ogog/public/images/tour/2.png
projects/ogog/public/images/tour/2.svg
projects/ogog/public/images/tour/3.png
projects/ogog/public/images/tour/3.svg
projects/ogog/public/images/tour/4.png
projects/ogog/public/images/tour/4.svg
projects/ogog/public/images/tour/5.png
projects/ogog/public/images/tour/5.svg
projects/ogog/public/images/tour/6.png
projects/ogog/public/images/tour/6.svg
projects/ogog/public/images/tour/7.png
projects/ogog/public/images/tour/7.svg
projects/ogog/public/javascripts/
projects/ogog/public/javascripts/application.js
projects/ogog/public/javascripts/controls.js
projects/ogog/public/javascripts/dragdrop.js
projects/ogog/public/javascripts/effects.js
projects/ogog/public/javascripts/prototype.js
projects/ogog/public/pub/
projects/ogog/public/pub/test/
projects/ogog/public/pub/test/lama/
projects/ogog/public/pub/test/lama/badgedindex.html
projects/ogog/public/pub/test/lama/feed/
projects/ogog/public/pub/test/lama/feed/feed.atom
projects/ogog/public/pub/test/lama/linkedindex.html
projects/ogog/public/pub/test/lama/posts/
projects/ogog/public/pub/test/lama/posts/post1.html
projects/ogog/public/pub/test/lama/posts/post2.html
projects/ogog/public/pub/test/lama/posts/post3.html
projects/ogog/public/pub/test/rules.htm
projects/ogog/public/robots.txt
projects/ogog/public/source.zip
projects/ogog/public/stylesheets/
projects/ogog/public/stylesheets/ogog-ie.css
projects/ogog/public/stylesheets/ogog-ie6.css
projects/ogog/public/stylesheets/ogog.css
projects/ogog/script/
projects/ogog/script/about
projects/ogog/script/breakpointer
projects/ogog/script/console
projects/ogog/script/destroy
projects/ogog/script/generate
projects/ogog/script/performance/
projects/ogog/script/performance/benchmarker
projects/ogog/script/performance/profiler
projects/ogog/script/plugin
projects/ogog/script/process/
projects/ogog/script/process/inspector
projects/ogog/script/process/reaper
projects/ogog/script/process/spawner
projects/ogog/script/runner
projects/ogog/script/server
projects/ogog/test/
projects/ogog/test/fixtures/
projects/ogog/test/fixtures/feeds.yml
projects/ogog/test/fixtures/memberships.yml
projects/ogog/test/fixtures/posts.yml
projects/ogog/test/fixtures/taggings.yml
projects/ogog/test/fixtures/tags.yml
projects/ogog/test/fixtures/users.yml
projects/ogog/test/fixtures/votes.yml
projects/ogog/test/functional/
projects/ogog/test/functional/post_controller_test.rb
projects/ogog/test/integration/
projects/ogog/test/mocks/
projects/ogog/test/mocks/development/
projects/ogog/test/mocks/test/
projects/ogog/test/test_helper.rb
projects/ogog/test/unit/
projects/ogog/test/unit/context_test.rb
projects/ogog/test/unit/extensions/
projects/ogog/test/unit/extensions/array_test.rb
projects/ogog/test/unit/extensions/fixnum_test.rb
projects/ogog/test/unit/extensions/float_test.rb
projects/ogog/test/unit/extensions/nil_class_test.rb
projects/ogog/test/unit/feed_test.rb
projects/ogog/test/unit/link_test.rb
projects/ogog/test/unit/membership_test.rb
projects/ogog/test/unit/post_test.rb
projects/ogog/test/unit/tag_test.rb
projects/ogog/test/unit/tagging_test.rb
projects/ogog/test/unit/user_test.rb
projects/ogog/test/unit/vote_test.rb
projects/ogog/tmp/
projects/ogog/tmp/cache/
projects/ogog/tmp/pids/
projects/ogog/tmp/sessions/
projects/ogog/tmp/sockets/
projects/ogog/vendor/
projects/ogog/vendor/plugins/
Added: projects/ogog/README
===================================================================
--- projects/ogog/README (rev 0)
+++ projects/ogog/README 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,5 @@
+The readme is found in:
+doc/README_FOR_APP
+
+and online at:
+http://www.ogog.org/pub/doc/app/
Added: projects/ogog/Rakefile
===================================================================
--- projects/ogog/Rakefile (rev 0)
+++ projects/ogog/Rakefile 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,10 @@
+# Add your own tasks in files placed in lib/tasks ending in .rake,
+# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
+
+require(File.join(File.dirname(__FILE__), 'config', 'boot'))
+
+require 'rake'
+require 'rake/testtask'
+require 'rake/rdoctask'
+
+require 'tasks/rails'
Added: projects/ogog/app/controllers/account_controller.rb
===================================================================
--- projects/ogog/app/controllers/account_controller.rb (rev 0)
+++ projects/ogog/app/controllers/account_controller.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,132 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+require "pathname"
+require "cgi"
+
+# load the openid library
+begin
+ require "rubygems"
+ require_gem "ruby-openid", ">= 1.0.2"
+rescue LoadError
+ require "openid"
+end
+
+class AccountController < ApplicationController
+ layout 'main'
+
+ ### Filters
+
+ before_filter :build_bodies,
+ : [:signup, :login, :forgot]
+
+ ### Bodies
+
+ url_bar_body :single_tagless_url_bar
+
+ ### Metheds
+
+ # Explanation + offer to signup with OpenID
+ #
+ def signup
+ end
+
+ # Help people out with forgotten passwords.
+ #
+ def forgot
+ end
+
+ # Processes the login request, disovers the openid server, and
+ # then redirects.
+ #
+ def login
+ openid_url = params[:account][:openid_url]
+ if request.post?
+ request = consumer.begin(openid_url)
+
+ case request.status
+ when OpenID::SUCCESS
+ return_to = url_for(:action => 'complete')
+ trust_root = url_for(:controller =>'')
+
+ url = request.redirect_url(trust_root, return_to)
+ redirect_to(url)
+ return
+ when OpenID::FAILURE
+ escaped_url = CGI::escape(openid_url)
+ flash[:notice] = "Could not find OpenID server for #{escaped_url}"
+ else
+ flash[:notice] = "An unknown error occured."
+ end
+ end
+ end
+
+ # Handles the openid server response.
+ #
+ def complete
+ response = consumer.complete(params)
+
+ case response.status
+ when OpenID::SUCCESS
+ @user = User.get(response.identity_url)
+
+ flash[:notice] = "Verified as #{response.identity_url}"
+
+ if @user.nil?
+ # create user object if one does not exist
+ session[:openid_url] = response.identity_url
+ redirect_to new_user_url()
+ else
+ session[:user_id] = @user.id
+ if request.env["HTTP_REFERER"].nil?
+ redirect_to index_url()
+ else
+ redirect_to :back
+ end
+ end
+ return
+ when OpenID::FAILURE
+ if response.identity_url
+ flash[:notice] = "Verification of #{CGI::escape(response.identity_url)} failed."
+ else
+ flash[:notice] = 'Verification failed.'
+ end
+ when OpenID::CANCEL
+ flash[:notice] = 'Verification cancelled.'
+ else
+ flash[:notice] = 'Unknown response from OpenID server.'
+ end
+ redirect_to :action => 'login'
+ end
+
+ # Terminates the session.
+ #
+ def logout
+ session[:user_id] = nil
+ User.reset
+ redirect_to :back
+ end
+
+ private
+
+ # Gets the OpenID::Consumer object.
+ #
+ def consumer
+ # create the OpenID store for storing associations and nonces,
+ # putting it in your app's db directory
+ store_dir = Pathname.new(RAILS_ROOT).join('db').join('openid-store')
+ store = OpenID::FilesystemStore.new(store_dir)
+
+ return OpenID::Consumer.new(session, store)
+ end
+end
Added: projects/ogog/app/controllers/application.rb
===================================================================
--- projects/ogog/app/controllers/application.rb (rev 0)
+++ projects/ogog/app/controllers/application.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,95 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class ApplicationController < ActionController::Base
+ ### Inclusions
+
+ # Pick a unique cookie name to distinguish our session data from others'
+ session :session_key => '_trunk_session_id'
+
+ include BodyBuilderModule # Bodies and body_parts.
+
+ ### Filters
+
+ before_filter :get_user, :resolve_context
+
+ ### Bodies
+
+ body_parts :url_bar, :left, :right
+
+ left_body :menu
+
+ right_body :sponsoring,
+ :except => [:index]
+
+ ### Filter functions
+
+ def get_user
+ if session[:user_id]
+ User.current = User.find(session[:user_id])
+ else
+ User.reset
+ end
+ return true
+ end
+
+ def resolve_context
+ if params[:link_string]
+ begin
+ Context.current = Context.new(Link.new_from_s(params[:link_string]))
+ rescue
+ Context.current = Context.new(Link.new_from_s(params[:link_string].split('/')[-3..-1].join('/')))
+ flash.now[:notice] = 'Only 3 stacked tags can be requested at the same time'
+ end
+ Context.current.resolve
+ else
+ Context.current = Context.new(Tag.or_new_from_s(params[:tag_string]))
+ end
+ end
+
+ ### Body functions
+
+ def menu
+ render_to_string(:partial => 'shared/menu',
+ :locals => {:action => params[:action]})
+ end
+
+ def sponsoring
+ render_to_string(:partial => 'shared/sponsoring')
+ end
+
+ ### Methods
+
+ def single_url_bar
+ url = url_for(params.merge(:only_path => true)).slice(1..-1).split('/')[0...-1].join(' / ')
+ render_to_string(:partial => 'shared/single_url_bar',
+ :locals => {:url => url, :tag => Context.current.tag})
+ end
+
+ def single_tagless_url_bar
+ url = url_for(params.merge(:only_path => true)).slice(1..-1).split('/').join(' / ')
+ render_to_string(:partial => 'shared/single_url_bar',
+ :locals => {:url => url, :tag => nil})
+ end
+
+ ### Hacks
+
+ def help
+ Helper.instance
+ end
+
+ class Helper
+ include Singleton
+ include ApplicationHelper
+ end
+end
Added: projects/ogog/app/controllers/doc_controller.rb
===================================================================
--- projects/ogog/app/controllers/doc_controller.rb (rev 0)
+++ projects/ogog/app/controllers/doc_controller.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,52 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class DocController < ApplicationController
+ layout 'main'
+
+ ### Filters
+
+ before_filter :build_bodies
+
+ ### Bodies
+
+ url_bar_body :single_tagless_url_bar
+
+ ### Filter functions
+
+ ### Methods
+
+ def tour
+ @slide_s = slide_s
+ end
+
+ def faq
+ end
+
+ def api
+ end
+
+ # AJAX
+
+ def slide
+ render :text => slide_s
+ end
+
+ # Private
+
+ private
+
+ def slide_s
+ render_to_string(:partial => 'slide', :locals => {:page => params[:page].to_i, :max => 7})
+ end
+end
Added: projects/ogog/app/controllers/download_controller.rb
===================================================================
--- projects/ogog/app/controllers/download_controller.rb (rev 0)
+++ projects/ogog/app/controllers/download_controller.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,55 @@
+#--#
+# Copyright: (c) 2006, 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the LogiLogi program. LogiLogi is free software. You
+# can run/distribute/modify LogiLogi under the terms of the Affero General
+# Public License version 1 or any later version. The Affero GPL states that
+# running a modified version or a derivative work also requires you to make
+# the sourcecode of that work available to everyone that can interact with
+# it. We chose the Affero GPL to ensure that LogiLogi remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class DownloadController < ApplicationController
+ def regenerate_source_archive
+ Zip::ZipFile.open("tmp/source.zip", Zip::ZipFile::CREATE) {|zipfile|
+ globs = Array.new
+ files = Array.new
+ files.push("Rakefile",
+ "README")
+ globs.push(File.join("app","**", "*.rb"))
+ globs.push(File.join("components","**", "*.rb"))
+ globs.push(File.join("config","**", "*.tmpl"))
+ files.push("config/routes.rb",
+ "config/environment.rb",
+ "config/boot.rb",
+ "config/daemons.yml")
+ globs.push(File.join("config/environments","**", "*.tmpl"))
+ globs.push(File.join("db","**", "*.rb"))
+ files.push("doc/LICENSE.txt",
+ "doc/README_FOR_APP")
+ globs.push(File.join("lib","**", "*.rb"))
+ globs.push(File.join("lib","**", "*.rake"))
+ globs.push(File.join("public","**", "[^.]*"))
+ globs.push(File.join("script","**", "[^.]*"))
+ globs.push(File.join("test","**", "*.rb"))
+ globs.push(File.join("test","**", "*.yml"))
+ globs.push(File.join("vendor","**", "[^.]*"))
+ globs.each {|glob|
+ files.concat(Dir.glob(glob))
+ }
+ files.each {|file_name|
+ if File.exists?(file_name)
+ zipfile.add(file_name,file_name)
+ end
+ }
+ }
+ File.rename("tmp/source.zip","public/source.zip")
+ end
+
+ def source
+ self.regenerate_source_archive
+ send_file "public/source.zip", :filename => 'source.zip'
+ end
+end
Added: projects/ogog/app/controllers/feed_controller.rb
===================================================================
--- projects/ogog/app/controllers/feed_controller.rb (rev 0)
+++ projects/ogog/app/controllers/feed_controller.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,98 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class FeedController < ApplicationController
+ layout 'main'
+
+ ### Filters
+
+ before_filter :find,
+ :except => [:new, :create]
+ before_filter :build_bodies,
+ :except => [:create, :update]
+
+ ### Bodies
+
+ url_bar_body :single_tagless_url_bar
+
+ ### Filter functions
+
+ def find
+ @feed = Feed.find(params[:id])
+ end
+
+ ### Body functions
+
+ ### Methods
+
+ # Crud
+
+ def index
+ end
+
+ def new
+ end
+
+ def create
+ @feed = Feed.new(:url => params[:feed][:url])
+ @feed.save
+ @feed.harvest
+ if !@feed.bad?
+ redirect_to claim_feed_url(@feed)
+ else
+ flash[:error] = 'Your feed could not be processed, check the url or the feed-status below'
+ redirect_to feed_url(@feed)
+ end
+ end
+
+ def claim
+ if request.method == :post
+ begin
+ @feed.claim
+ flash[:notice] = 'Successfully claimed feed'
+ redirect_to feed_url(@feed)
+ rescue
+ flash[:error] = $!
+ end
+ end
+ end
+
+ def show
+ @last_posts_s = last_posts_s
+ end
+
+ def edit
+ end
+
+ def update
+ end
+
+ def delete
+ end
+
+ # AJAX
+
+ def last_posts
+ render :text => last_posts_s
+ end
+
+ # Private
+
+ def last_posts_s
+ pages = Paginator.new(self, @feed.posts.count, 7, params[:page])
+ posts = @feed.posts.find(:all, :limit => pages.items_per_page, :offset => pages.current.offset,
+ :order => 'published_at DESC')
+ render_to_string(:partial => 'last_posts', :locals => {
+ :pages => pages, :posts => posts, :feed => @feed})
+ end
+end
Added: projects/ogog/app/controllers/post_controller.rb
===================================================================
--- projects/ogog/app/controllers/post_controller.rb (rev 0)
+++ projects/ogog/app/controllers/post_controller.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,118 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class PostController < ApplicationController
+ layout 'main'
+
+ ### Filters
+
+ before_filter :find,
+ :except => [:index, :new_posts, :top_posts]
+ before_filter :build_bodies
+
+ ### Bodies
+
+ url_bar_body :double_url_bar,
+ : [:index]
+ url_bar_body :single_url_bar,
+ :except => [:index]
+
+# left_body :cloud,
+# : [:index]
+ left_body :viewpoints,
+ : [:viewpoint]
+
+ ### Filter functions
+
+ def find
+ @post = Post.find(params[:id])
+ end
+
+ ### Body functions
+
+ def double_url_bar
+ render_to_string(:partial => 'double_url_bar')
+ end
+
+ def cloud
+ tags = Tag.top_tags(Context.current.link.received_tags, :order => "count DESC, word", :limit => 100).
+ sort_by {|tag| tag.word}
+ render_to_string(:partial => 'cloud',
+ :locals => {:tags => tags})
+ end
+
+ def viewpoints
+ render_to_string(:partial => 'viewpoints',
+ :locals => {
+ :post => @post,
+ :taggings => @post.taggings.order_by_score,
+ :current_tagging => @post.tagging_for(Context.current.tag)})
+ end
+
+ ### Methods
+
+ def index
+ @new_posts_s = new_posts_s
+ @top_posts_s = top_posts_s
+ end
+
+ def viewpoint
+ end
+
+ # Misc
+
+ def rate
+ if !params[:score] or !params[:id]
+ raise 'Missing parameter'
+ end
+ @post.rate(params[:score].to_i, Context.current.tag, request.env['REMOTE_ADDR'])
+ end
+
+ # AJAX
+
+ def new_posts
+ render :text => new_posts_s
+ end
+
+ def top_posts
+ render :text => top_posts_s
+ end
+
+ # Private
+
+ private
+
+ def new_posts_s
+ conditions = 'p.published_at >= "' + 1.week.ago.to_s(:db) + '"'
+ received_tags = Context.current.link.received_tags
+ pages = Paginator.new(self,
+ Tagging.count_posts_for(received_tags, :conditions => conditions), 7, params[:page])
+ posts = Tagging.top_posts_for(received_tags, :conditions => conditions,
+ :limit => pages.items_per_page, :offset => pages.current.offset)
+ render_to_string(:partial => 'posts', :locals => {
+ :pages => pages, :posts => posts, :update => 'new_posts_s',
+ :action => :new_posts, :link_string => Context.current.link.to_s})
+ end
+
+ def top_posts_s
+ conditions = 'p.published_at < "' + 1.week.ago.to_s(:db) + '"'
+ received_tags = Context.current.link.received_tags
+ pages = Paginator.new(self,
+ Tagging.count_posts_for(received_tags, :conditions => conditions), 7, params[:page])
+ posts = Tagging.top_posts_for(received_tags,:conditions => conditions,
+ :limit => pages.items_per_page, :offset => pages.current.offset)
+ render_to_string(:partial => 'posts', :locals => {
+ :pages => pages, :posts => posts, :update => 'top_posts_s',
+ :link_string => Context.current.link.to_s, :action => :top_posts})
+ end
+end
Added: projects/ogog/app/controllers/user_controller.rb
===================================================================
--- projects/ogog/app/controllers/user_controller.rb (rev 0)
+++ projects/ogog/app/controllers/user_controller.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,164 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class UserController < ApplicationController
+ layout 'main'
+
+ ### Filters
+
+ before_filter :find
+ before_filter :order_memberships,
+ : [:show]
+ before_filter :build_bodies
+
+ ### Bodies
+
+ url_bar_body :single_tagless_url_bar
+
+ left_body :cloud,
+ : [:index]
+ left_body :badges,
+ : [:show]
+
+ ### Filter functions
+
+ def find
+ if params[:openid_url]
+ @user = User.find_by_openid_url(params[:openid_url])
+ else
+ @user = User.find_by_name(params[:id])
+ end
+ if !@user
+ respond_to do |format|
+ format.html do
+ flash[:warning] = 'Requested user does not exist'
+ redirect_to main_url()
+ end
+ format.json do
+ render :json => {}.to_json
+ end
+ format.xml do
+ render :xml => {}.to_xml(:root => 'badge')
+ end
+ end
+ return false
+ end
+ end
+
+ def order_memberships
+ @memberships = @user.memberships.order_by_percentile
+ end
+
+ ### Body functions
+
+ def cloud
+ render_to_string(:partial => 'cloud')
+ end
+
+ def badges
+ render_to_string(:partial => 'badges',
+ :locals => {:user => @user, :memberships => @memberships})
+ end
+
+ ### CRUD-methods
+
+ def index
+ end
+
+ def new
+ if session[:openid_url]
+ @user = User.new(:name => User.suggest_word_from_openid_url(session[:openid_url]))
+ else
+ flash.now[:warning] = "You need to have cookies enabled to create and use an account. Enable them and login again."
+ end
+ end
+
+ def create
+ if session[:openid_url]
+ begin
+ params[:user][:openid_url] = session[:openid_url]
+ @user = User.new(params[:user])
+ User.transaction(@user) do
+ if @user.save
+ session[:openid_url] = nil
+ session[:user_id] = @user.id
+ redirect_to user_url(:id => @user.name)
+ else
+ flash[:warning] = "User account could not be created! Please retry."
+ redirect_to new_user_url()
+ end
+ end
+ rescue
+ flash[:warning] = "Error creating User. Please try again later."
+ redirect_to new_user_url()
+ end
+ else
+ flash[:warning] = "Your openid_url was lost from the session. Please report this bug."
+ redirect_to new_user_url()
+ end
+ end
+
+ def show
+ @last_posts = @user.last_posts
+ end
+
+ def badge
+ percentile = @user.percentile_for(Context.current.tag)
+ respond_to do |format|
+ format.html
+ format.json do
+ render :json => {
+ :tag => Context.current.tag.to_s,
+ :percentile => percentile,
+ :power => @user.voting_power_for(Context.current.tag),
+ :user => @user.name}.to_json
+ end
+ format.xml do
+ render :xml => {
+ :tag => Context.current.tag.to_s,
+ :percentile => percentile,
+ :power => @user.voting_power_for(Context.current.tag),
+ :user => @user.name}.to_xml(:root => 'badge')
+ end
+ format.png do
+ percentile = percentile.round
+ img = Magick::ImageList.new("#{RAILS_ROOT}/public/images/badge-logo.png")
+
+ text = Magick::Draw.new
+ text.font_family = 'verdana'
+
+ text.annotate(img, 0,0,5,7, @user.full_name) {
+ self.pointsize = 10
+ self.gravity = Magick::NorthWestGravity
+ }
+ text.annotate(img, 0,0,5,-3, help.percentile_in_words(percentile) + ' at') {
+ self.pointsize = 10
+ self.gravity = Magick::WestGravity
+ }
+ text.annotate(img, 0,0,0,5, Context.current.tag.to_s) {
+ self.pointsize = 15
+ self.gravity = Magick::SouthGravity
+ }
+ text.annotate(img, 0,0,(percentile == 100 ? 5 : (percentile < 10 ? 16 : 10)),11, percentile.to_s) {
+ self.pointsize = 24
+ self.font_weight = Magick::BoldWeight
+ self.gravity = Magick::NorthEastGravity
+ }
+
+ send_data img.to_blob, :filename => "badge.png",
+ :disposition => 'inline',
+ :type => 'image/png'
+ end
+ end
+ end
+end
Added: projects/ogog/app/helpers/application_helper.rb
===================================================================
--- projects/ogog/app/helpers/application_helper.rb (rev 0)
+++ projects/ogog/app/helpers/application_helper.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,128 @@
+# Methods added to this helper will be available to all templates in the application.
+module ApplicationHelper
+ include Rubaidh::TabularForm
+
+ def link_to_tag(tag, options = {})
+ link_to(tag.to_s, index_url({:link_string => tag.to_s}),options)
+ end
+
+ def link_to_post(string, post, tag, options = {})
+ link_to string, show_url({:tag_string => tag.to_s,
+ :action => 'viewpoint', :id => post}.merge(options))
+ end
+
+ def link_to_user(user)
+ link_to user.name, user_url(:id => user.name)
+ end
+
+ def link_to_feed(feed)
+ link_to feed.title, feed_url(feed)
+ end
+
+ def score_image(score)
+ if score.nil?
+ image = 'star'
+ else
+ image = (score >= 0 ? 'star' : 'skull')
+ end
+ # Below is a hack for the DXImageTransform IE CSS hack
+ return '<div class="score_image score_image_' + image + '">' +
+ image_tag(image + '.png', :class => 'score', :size => '90x90') +
+ '</div>'
+ end
+
+ def score_nr(score)
+ (score ? number_with_precision(score, 1) : '~')
+ end
+
+ def tagging_score(tagging)
+ '<span class="score">' + score_nr(tagging.score) + '</span>'
+ end
+
+ def membership_percentile(membership)
+ '<span class="percentile fixed">' + number_with_precision(membership.percentile, 1) + ' %</span>'
+ end
+
+ def tagging_power(tagging)
+ voting_power(tagging.weight)
+ end
+
+ def voting_power(voting_power)
+ '<span class="power">' + number_with_precision(voting_power, 1) + '</span>'
+ end
+
+ def score_in_words(score)
+ if score.nil?
+ Tagging::SCORES[score]
+ else
+ Tagging::SCORES[score.round]
+ end
+ end
+
+ def percentile_in_words(percentile)
+ if percentile <= 10
+ return 'just started'
+ else
+ score = ((percentile - 10) / 18.0).ceil
+ return Tagging::SCORES[score]
+ end
+ end
+
+ def display_standard_flashes
+ flashes = []
+ if flash[:error]
+ flashes << ['Error: ' + flash[:error], 'error']
+ end
+ if flash[:warning]
+ flashes << [flash[:warning], 'warning']
+ end
+ if flash[:notice]
+ flashes << [flash[:notice], 'notice']
+ end
+ if flashes.empty?
+ return
+ end
+ content = flashes.collect { |flash_arr|
+ content_tag('span', flash_arr[0], :class => "#{flash_arr[1]}")
+ }
+ if !flashes.empty?
+ content_tag('div', content.join('<br />'), :id => 'flash', :class => 'box large noticable')
+ else
+ ''
+ end
+ end
+
+ def ajax_pagination_links(paginator, options={})
+ options[:params].delete(:page)
+ options.merge!(ActionView::Helpers::PaginationHelper::DEFAULT_OPTIONS) {|key, old, new| old}
+
+ window_pages = paginator.current.window(options[:window_size]).pages
+
+ return if window_pages.length <= 1 unless
+ options[:link_to_current_page]
+
+ first, last = paginator.first, paginator.last
+
+ returning html = '' do
+ if options[:always_show_anchors] and not window_pages[0].first?
+ html << link_to_remote(first.number, :update => options[:update], :url => { options[:name] => first }.update(options[:params] ))
+ html << ' ... ' if window_pages[0].number - first.number > 1
+ html << ' '
+ end
+
+ window_pages.each do |page|
+ if paginator.current == page && !options[:link_to_current_page]
+ html << page.number.to_s
+ else
+ html << link_to_remote(page.number, :update => options[:update], :url => { options[:name] => page }.update(options[:params] ))
+ end
+ html << ' '
+ end
+
+ if options[:always_show_anchors] && !window_pages.last.last?
+ html << ' ... ' if last.number - window_pages[-1].number > 1
+ html << link_to_remote(paginator.last.number, :update => options[:update], :url => { options[:name] => last }.update( options[:params]))
+ end
+ end
+ end
+end
Added: projects/ogog/app/helpers/feed_helper.rb
===================================================================
--- projects/ogog/app/helpers/feed_helper.rb (rev 0)
+++ projects/ogog/app/helpers/feed_helper.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,2 @@
+module FeedHelper
+end
Added: projects/ogog/app/helpers/post_helper.rb
===================================================================
--- projects/ogog/app/helpers/post_helper.rb (rev 0)
+++ projects/ogog/app/helpers/post_helper.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,40 @@
+module PostHelper
+ def context_url_bar_link(options)
+ link = Context.current.link
+ link_url = '<ul>'
+ (0...(link.size(options[:direction]))).each { |i|
+ link_url += '<li>' + link_to(link.tags(options[:direction])[i],
+ {:action => 'index', :link_string => link.to_s(
+ :direction => options[:direction], :step => i)}) +
+ '</li><li><span class="slash_separator">/</span></li>'
+ }
+ link_url.slice!(-47..-1) # slice off separator-span again
+ return link_url + '</ul>'
+ end
+
+ def tag_cloud(tags, classes)
+ max, min = 0, 0
+ tags.each { |tag|
+ count = tag.count.to_i
+ max = count if count > max
+ min = count if count < min
+ }
+
+ divisor = ((max - min) / classes.size) + 1
+
+ tags.each { |tag|
+ yield tag, classes[(tag.count.to_i - min) / divisor]
+ }
+ end
+
+ def link_to_cloud_tag(tag, css_class)
+ context = Context.current
+ link = '<span class="cloud ' + css_class + '">' + link_to(truncate(tag.to_s, 20), index_url({:link_string => tag.to_s})) + ' '
+ if tag != Tag.overall && !context.link.requested_tags.include?(tag)
+ link << link_to('/+', index_url({:link_string => context.link.to_s + '/' + tag.to_s}))
+ else
+ link << '/~'
+ end
+ return link + '</span>'
+ end
+end
Added: projects/ogog/app/helpers/user_helper.rb
===================================================================
--- projects/ogog/app/helpers/user_helper.rb (rev 0)
+++ projects/ogog/app/helpers/user_helper.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,2 @@
+module UserHelper
+end
Added: projects/ogog/app/models/context.rb
===================================================================
--- projects/ogog/app/models/context.rb (rev 0)
+++ projects/ogog/app/models/context.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,53 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+#
+# Used to store the user location...
+
+class Context
+ ### Relationships
+
+ cattr_accessor :current
+ attr_accessor :link, :tag
+
+ ### Constructors
+
+ # Creates a new context and sets it as the current Context.
+ #
+ def initialize(link_or_tag)
+ if link_or_tag.kind_of?(Link)
+ self.link = link_or_tag
+ else
+ self.tag = link_or_tag
+ end
+ end
+
+ # Makes sure that the given context/tag-string will be set with the
+ # default tag if empty.
+ #
+ def self.assert_tag(string)
+ if string.nil? or string.size == 0
+ return OgOg::Config::OVERALL_TAG_STRING
+ else
+ return string
+ end
+ end
+
+ ### Methods
+
+ # Resolves the link and sets the tag.
+ #
+ def resolve
+ self.link.resolve
+ self.tag = self.link.received_tags.last
+ end
+end
Added: projects/ogog/app/models/feed.rb
===================================================================
--- projects/ogog/app/models/feed.rb (rev 0)
+++ projects/ogog/app/models/feed.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,140 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+#
+# Feeds are sources of posts through RSS...
+
+class Feed < ActiveRecord::Base
+ ### Relationships
+
+ belongs_to :user
+ has_many :posts
+
+ ### Constants
+
+ GOOD = 0
+ NO_TITLE = 1
+ NO_SITE_URL = 2
+ INCOMPLETE_POSTS = 3
+ FUTURE_DATE = 4
+ NOT_PARSABLE = 5
+ NO_PUBLISH_DATE = 6
+
+ ### Validations
+
+ validates_presence_of :url
+ validates_uniqueness_of :url
+
+ ### Functions
+
+ # Extracts tags or categories
+ #
+ def self.get_item_tags(new_item)
+ if new_item.tags.empty?
+ return new_item.categories.collect {|c| c.term}
+ else
+ return new_item.tags
+ end
+ end
+
+ ### Methods
+
+ # Returns true if the status is anything but GOOD
+ #
+ def bad?
+ return self.status != GOOD
+ end
+
+ # Checks the feed for new entries and harvests them into new posts.
+ #
+ def harvest
+ if !self.bad?
+ begin
+ f = FeedTools::Feed.open(self.url)
+ rescue
+ self.status = NOT_PARSABLE
+ end
+ if self.title != f.title
+ self.title = f.title
+ end
+ if self.site_url != f.link
+ self.site_url = f.link
+ end
+ if self.title.nil?
+ self.status = NO_TITLE
+ end
+ if self.site_url.nil?
+ self.status = NO_SITE_URL
+ end
+ if !self.bad? and f.items.detect {|i| i.published.nil?}
+ self.status = NO_PUBLISH_DATE
+ end
+ if !self.bad?
+ f.items.select {|i| !self.harvested_publication_time or
+ i.published > self.harvested_publication_time}.sort_by {|i| i.published}.each do |new_item|
+ if !self.bad?
+ p = Post.new(:feed => self, :title => new_item.title, :body => new_item.content,
+ :url => new_item.link, :published_at => new_item.published.utc)
+ if p.published_at > Time.now + 1.day
+ self.status = FUTURE_DATE
+ end
+ if !p.valid?
+ self.status = INCOMPLETE_POSTS
+ end
+ end
+ if !self.bad?
+ p.save
+ p.set_tags(Feed.get_item_tags(new_item) + self.tag_strings)
+ # At least one tag is set, guaranteed...
+ self.harvested_publication_time = p.published_at
+ end
+ end
+ end
+ self.save
+ end
+ end
+
+ # Claims the feed for the current user.
+ #
+ def claim
+ if User.current.nil?
+ raise 'You need to be logged in to claim a feed'
+ elsif !self.user.nil?
+ raise 'This feed has already been claimed'
+ else
+ html = URI.parse(self.site_url)
+ s = Scraper.define {
+ process 'img[src*="ogog.org/user/' + User.current.name + '"]', :found => true
+ process 'a[href*="ogog.org/user/' + User.current.name + '"]', :found => true
+ result :found
+ }
+ if s.scrape(html)
+ self.user = User.current
+ self.save
+ else
+ raise 'Unable to claim: no badge or link to your OgOg user-page found, check the spelling of your urls'
+ end
+ end
+ end
+
+ # Returns the most recent post in this feed
+ #
+ def last_post
+ self.posts.find(:first, :order => 'published_at DESC')
+ end
+
+ # Ad hoc, returns the tag-strings for this feed.
+ #
+ def tag_strings
+ self.tags_string.split(',')
+ end
+end
Added: projects/ogog/app/models/link.rb
===================================================================
--- projects/ogog/app/models/link.rb (rev 0)
+++ projects/ogog/app/models/link.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,111 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class Link
+ ### Relationships
+
+ attr_accessor :requested_tags, :received_tags
+
+ ### Constructors
+
+ # Creates a new Link with the given tags.
+ #
+ def initialize(tags)
+ if tags.size > OgOg::Config::MAXIMUM_LINK_SIZE
+ raise 'Too many tags requested'
+ elsif tags.empty?
+ tags = [Tag.overall]
+ end
+ self.requested_tags = tags
+ self.received_tags = []
+ end
+
+ # Creates a new Link from a string.
+ #
+ def self.new_from_s(tag_string)
+ return Link.new(tag_string.split('/').collect {|s| Tag.or_new_from_s(s)})
+ end
+
+ ### Methods
+
+ # Resolves the link, calculating the received_tags.
+ #
+ def resolve
+ existing_tags = self.existing_requested_tags
+ while !Tagging.any_posts_for?(existing_tags) and existing_tags.size > 0
+ existing_tags.shift
+ end
+ if existing_tags.size == 0
+ existing_tags.push(Tag.overall)
+ end
+ self.received_tags = existing_tags
+ end
+
+ # Returns the size of this link in the given direction.
+ #
+ def size(direction)
+ self.tags(direction).size
+ end
+
+ # Returns the tags of this link in the given direction.
+ #
+ def tags(direction = :requested)
+ if direction == :requested
+ return self.requested_tags
+ else
+ return self.received_tags
+ end
+ end
+
+ # Returns the existing requested tags.
+ #
+ def existing_requested_tags
+ self.requested_tags.reject {|t| t.new_record?}
+ end
+
+ # Adds a tag to this link. If the maximum link size is reached the
+ # last tag is replaced by the added tag.
+ #
+ def add_tag(tag)
+ if self.requested_tags.size == OgOg::Config::MAXIMUM_LINK_SIZE
+ self.requested_tags.pop
+ end
+ self.requested_tags << tag
+ end
+
+ # Turns the link into a string.
+ #
+ # Options:
+ # * :direction => :requested: requested tags are used, :received:
+ # received tags are used.
+ # * :step => upto which linkpart to show.
+ #
+ def to_s(options = {})
+ options[:direction] ||= :requested
+ if options[:direction] == :requested
+ tags = self.requested_tags
+ else
+ tags = self.received_tags
+ end
+ options[:step] ||= tags.size
+ return tags[0..options[:step]].collect {|t| t.to_s}.join('/')
+ end
+
+ # Creates a new link with the same requested and received tags.
+ #
+ def dup
+ l = Link.new(self.requested_tags.dup)
+ l.received_tags = self.received_tags.dup
+ return l
+ end
+end
Added: projects/ogog/app/models/membership.rb
===================================================================
--- projects/ogog/app/models/membership.rb (rev 0)
+++ projects/ogog/app/models/membership.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,47 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class Membership < ActiveRecord::Base
+ ### Relationships
+
+ belongs_to :user
+ belongs_to :tag
+
+ ### Functions
+
+ # Returns the anonymous voting power.
+ #
+ def self.anonymous_voting_power
+ return OgOg::Config::ANONYMOUS_VOTING_POWER
+ end
+
+ # Returns the account voting power.
+ #
+ def self.account_voting_power
+ return OgOg::Config::ACCOUNT_VOTING_POWER
+ end
+
+ # (Re-)calculates the percentiles for the users.
+ #
+ def self.calculate_percentiles
+ Tag.find(:all).each do |tag|
+ count = tag.memberships.count.to_f
+ counter = count
+ tag.memberships.order_by_power.each do |membership|
+ membership.percentile = (counter / count) * 100
+ membership.save
+ counter -= 1
+ end
+ end
+ end
+end
Added: projects/ogog/app/models/post.rb
===================================================================
--- projects/ogog/app/models/post.rb (rev 0)
+++ projects/ogog/app/models/post.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,134 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+
+class Post < ActiveRecord::Base
+ ### Relationships
+
+ belongs_to :feed
+ has_many :taggings
+ has_many :tags, :through => :taggings
+
+ ### Validations
+
+ validates_presence_of :title, :body, :url
+
+ ### Filters
+
+ before_save :set_snippet
+
+ ### Filter Functions
+
+ # Sets the snippet to the first 245 characters of the body and makes
+ # sure that all HTML-tags will be neatly closed (a TODO).
+ #
+ def set_snippet
+ self.snippet = self.body[0..245]
+ end
+
+ ### Functions
+
+ # Gets the tags from URI-parsed html.
+ #
+ def self.get_tags(html)
+ s = Scraper.define {
+ array :tags
+ process 'a[href][rel~=tag]', :tags => :text
+ result :tags
+ }
+ return s.scrape(html)
+ end
+
+ ### Methods
+
+ # Gets the tags for this post. If the tags-array is not empty those
+ # are used. Otherwise tries to scrape them with get_tags.
+ #
+ # Also assigns the default Overall tag.
+ #
+ def set_tags(tags)
+ if tags.empty?
+ tags = Post.get_tags(URI.parse(self.url)) || []
+ end
+ tags.each do |t|
+ self.tag(Tag.or_new_from_s(t))
+ end
+ self.tag(Tag.overall)
+ end
+
+ # Adds the given tag if it is not already there.
+ #
+ def tag(tag)
+ if !self.taggings.find_by_tag_id(tag.id)
+ self.taggings.create(:post => self, :tag => tag)
+ end
+ end
+
+ # Removes the given tag.
+ #
+ def untag(tag)
+ if self.taggings.find_by_tag_id(tag.id)
+ self.taggings.find_by_tag_id(tag.id).destroy
+ end
+ end
+
+ # Returns the score this post has for the given tag.
+ #
+ def tagging_for(tag)
+ tagging = self.taggings.find_by_tag_id(tag.id)
+ if tagging.nil?
+ raise 'This post is not tagged with the requested tag'
+ end
+ return tagging
+ end
+
+ # Returns the best tags.
+ #
+ def best_tag
+ return self.taggings.order_by_score.first.tag
+ end
+
+ # Rates this post with the given score & power for the given tag.
+ #
+ def rate(score, tag, ip_address)
+ # checks
+ if score < -2 or score > 5
+ raise 'Score out of bounds -2, 5'
+ end
+ # weight determination
+ if !User.anonymous?
+ weight = User.current.voting_power_for(tag)
+ else
+ weight = Membership.anonymous_voting_power
+ end
+ tagging = self.taggings.find_by_tag_id(tag.id)
+ # registration
+ tagging.votes.build(:user => User.current, :weight => weight, :score => score,
+ :ip_address => ip_address)
+ # calculation
+ if tagging.rated?
+ old_power_income = tagging.power_income
+ tagging.score = ((tagging.score * tagging.weight) + (score * weight)) / (tagging.weight + weight)
+ tagging.weight += weight
+ else
+ old_power_income = 0
+ tagging.score = score
+ tagging.weight = weight
+ end
+ # power distribution
+ if !self.feed.user.nil?
+ self.feed.user.update_power(old_power_income, tagging.power_income, tag)
+ end
+ # saving
+ tagging.save
+ end
+end
Added: projects/ogog/app/models/tag.rb
===================================================================
--- projects/ogog/app/models/tag.rb (rev 0)
+++ projects/ogog/app/models/tag.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,98 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+#
+# Tags function as categories.
+
+class Tag < ActiveRecord::Base
+ ### Inclusions
+
+ include Comparable
+
+ ### Relationships
+
+ has_many :taggings
+ has_many :memberships
+
+ ### Functions
+
+ # Returns the OVERALL_TAG_STRING-tag.
+ #
+ def self.overall
+ Tag.or_new_from_s(OgOg::Config::OVERALL_TAG_STRING)
+ end
+
+ # Looks up the Tag for the given word_string in the db. If it's not
+ # found a new Tag is created for this word.
+ #
+ def self.or_new_from_s(word_string)
+ # checking
+ if word_string.nil?
+ return Tag.overall
+ end
+
+ # cleaning
+ word_string.gsub!(/[^\w\s-]/,' ')
+ word_string.squeeze!(' ')
+ word_string.strip!
+ word_string = word_string.titleize.split(" ").join("_")
+
+ # checking
+ if word_string.empty? or word_string == ' '
+ word_string = OgOg::Config::OVERALL_TAG_STRING
+ end
+
+ # resolving
+ tag = Tag.find_by_word(word_string)
+ if tag
+ return tag
+ else
+ return Tag.new(:word => word_string)
+ end
+ end
+
+ # Returns Tags for display in a cloud.
+ #
+ def self.top_tags(received_tags, options = {})
+ sql = "SELECT t.*, count(*) AS count FROM tags AS t, taggings AS n"
+ counter = 0
+ received_tags.each {|t|
+ sql << ', taggings AS n' + counter.to_s
+ counter += 1
+ }
+ sql << ' WHERE '
+ counter = 0
+ received_tags.each {|t|
+ sql << 'n' + counter.to_s + '.tag_id = ' + t.id.to_s + ' AND ' \
+ << 'n.post_id = n' + counter.to_s + '.post_id AND '
+ counter += 1
+ }
+ sql << "t.id = n.tag_id GROUP BY n.tag_id "
+ sql << " ORDER BY #{options[:order]}" if options[:order] != nil
+ sql << " LIMIT #{options[:limit]}" if options[:limit] != nil
+ tags = Tag.find_by_sql(sql)
+ end
+
+ ### Methods
+
+ # Makes tags comparable.
+ #
+ def <=>(other)
+ return self.word <=> other.word
+ end
+
+ # Turns a tag into a string
+ #
+ def to_s
+ return self.word
+ end
+end
Added: projects/ogog/app/models/tagging.rb
===================================================================
--- projects/ogog/app/models/tagging.rb (rev 0)
+++ projects/ogog/app/models/tagging.rb 2007-05-20 09:51:03 UTC (rev 283)
@@ -0,0 +1,156 @@
+#--#
+# Copyright: (c) 2007 The LogiLogi Foundation <fou...@lo...>
+#
+# License:
+# This file is part of the OgOg program. OgOg is free software. You can run/
+# distribute/modify OgOg under the terms of the Affero General Public
+# License version 1 or any later version. The Affero GPL states that running
+# a modified version or a derivative work also requires you to make the
+# sourcecode of that work available to everyone that can interact with it.
+# We chose the Affero GPL to ensure that OgOg remains open and libre
+# (doc/LICENSE.txt contains the full text of the legally binding license).
+#++#
+#
+# Join-class between Posts and Tags.
+#
+# Votes are associated with this class.
+
+class Tagging < ActiveRecord::Base
+ ### Relationships
+
+ belongs_to :tag
+ belongs_to :post
+ has_many :votes
+
+ ### Constants
+
+ SCORES = {
+ -2 => 'horrible',
+ -1 => 'bad',
+ nil => 'unrated',
+ 0 => 'neutral',
+ 1 => 'fair',
+ 2 => 'ok',
+ 3 => 'good',
+ 4 => 'perfect',
+ 5 => 'unsurpassed'
+ }
+
+ ### Filters
+
+ before_save :track_negativity
+
+ ### Filter-functions
+
+ def track_negativity
+ if self.rated? and self.score < 0
+ self.negative_as_of = Time.now
+ else
+ self.negative_as_of = nil
+ end
+ end
+
+ ### Functions
+
+ # Returns true if there exists any post for the given tags
+ #
+ def self.any_posts_for?(existing_tags)
+ return Tagging.top_posts_for(existing_tags).size > 0
+ end
+
+ # Counts the posts for the given tags + options.
+ #
+ # Valid options are:
+ # * :conditions => sql-like conditions, the posts table is called p
+ #
+ def self.count_posts_for(existing_tags, options = {})
+ if existing_tags.size > 0
+ sql = Tagging.sql_for_posts_for(
+ existing_tags, 'COUNT(p.id)', options[:conditions])
+ return ActiveRecord::Base.connection.select_value(sql).to_i
+ else
+ return 0
+ end
+ end
+
+ # Gets the top-posts for the given tags.
+ #
+ # Valid options are:
+ # * :conditions => sql-like conditions, the posts table is called p
+ # * :limit => limits the result-set to the given number
+ # * :offset => offsets the result-set by this number
+ #
+ def self.top_posts_for(existing_tags, options = {})
+ if existing_tags.size > 0
+ sql = Tagging.sql_for_posts_for(
+ existing_tags, 'DISTINCT p.*', options[:conditions])
+ sql << 'ORDER BY t' + (existing_tags.size - 1).to_s + '.score DESC '
+# sql << 'ORDER BY IF(t' + (existing_tags.size - 1).to_s + '.score IS NULL' +
+# ', -0.0000001, t' + (existing_tags.size - 1).to_s + '.score) DESC '
+ if options[:limit]
+ sql << 'LIMIT ' + options[:limit].to_s + ' '
+ if options[:offset]
+ sql << 'OFFSET ' + options[:offset].to_s + ' '
+ end
+ end
+ sql.slice!(-1)
+ Post.find_by_sql(sql)
+ else
+ return []
+ end
+ end
+
+ # Inner function that prepares the shared part of the sql.
+ #
+ def self.sql_for_posts_for(existing_tags, sel...
[truncated message content] |