├── lib
└── tasks
│ └── .gitkeep
├── .rspec
├── vendor
├── plugins
│ └── .gitkeep
└── assets
│ ├── stylesheets
│ ├── icon.css
│ ├── reset.css
│ ├── code.css
│ ├── wmd.css
│ ├── form.css
│ └── 960gs.css
│ └── javascripts
│ └── jquery.flash.js
├── app
├── helpers
│ ├── items_helper.rb
│ ├── pages_helper.rb
│ ├── users_helper.rb
│ ├── comments_helper.rb
│ ├── searches_helper.rb
│ ├── sessions_helper.rb
│ ├── authentications_helper.rb
│ └── application_helper.rb
├── assets
│ ├── images
│ │ ├── feed.png
│ │ ├── guest.png
│ │ ├── github_64.png
│ │ ├── hpc128x92.png
│ │ ├── open_id_64.png
│ │ ├── twitter_64.png
│ │ ├── icon-sprite.png
│ │ ├── wmd-buttons.png
│ │ ├── railsclub128x92.png
│ │ ├── travis-ci50x50.png
│ │ ├── iosonrails120x120.png
│ │ └── digitalocean-badge-gray.png
│ ├── javascripts
│ │ └── application.js
│ └── stylesheets
│ │ └── application.css
├── views
│ ├── comments
│ │ ├── _preview.html.erb
│ │ ├── _comment.html.erb
│ │ ├── _form.html.erb
│ │ ├── _new.html.erb
│ │ └── create.js.erb
│ ├── items
│ │ ├── _preview.html.erb
│ │ ├── edit.html.erb
│ │ ├── new.html.erb
│ │ ├── index.rss.builder
│ │ ├── _form.html.erb
│ │ ├── index.html.erb
│ │ └── show.html.erb
│ ├── pages
│ │ └── show.html.erb
│ ├── sessions
│ │ └── new.html.erb
│ ├── searches
│ │ └── index.html.erb
│ ├── users
│ │ ├── index.html.erb
│ │ └── show.html.erb
│ └── layouts
│ │ └── application.html.erb
├── models
│ ├── search.rb
│ ├── comment.rb
│ ├── ability.rb
│ ├── item.rb
│ ├── authentication.rb
│ └── user.rb
└── controllers
│ ├── sessions_controller.rb
│ ├── pages_controller.rb
│ ├── searches_controller.rb
│ ├── comments_controller.rb
│ ├── users_controller.rb
│ ├── authentications_controller.rb
│ ├── items_controller.rb
│ └── application_controller.rb
├── Procfile
├── public
├── favicon.ico
├── markdown-reference
│ ├── images
│ │ ├── arrow_down.gif
│ │ └── arrow_right.gif
│ ├── javascripts
│ │ └── guide.js
│ ├── LICENCE
│ ├── README.md
│ ├── stylesheets
│ │ └── markdown-reference.css
│ ├── sv
│ │ └── index.html
│ ├── ru
│ │ └── index.html
│ ├── fr
│ │ └── index.html
│ ├── en
│ │ └── index.html
│ ├── ca
│ │ └── index.html
│ ├── tr
│ │ └── index.html
│ ├── index.html
│ └── es
│ │ └── index.html
├── robots.txt
├── 404.html
├── 422.html
└── 500.html
├── config
├── locales
│ ├── searches.ru.yml
│ ├── comments.ru.yml
│ ├── authentications.ru.yml
│ ├── pagination.ru.yml
│ ├── users.ru.yml
│ ├── cancan.ru.yml
│ ├── sessions.ru.yml
│ ├── layouts.ru.yml
│ ├── items.ru.yml
│ ├── pages.ru.yml
│ ├── activerecord.ru.yml
│ └── active_support.yml
├── initializers
│ ├── bugsnag.rb
│ ├── mime_types.rb
│ ├── action_mailer.rb
│ ├── omniauth.rb
│ ├── backtrace_silencers.rb
│ ├── session_store.rb
│ ├── secret_token.rb
│ ├── wrap_parameters.rb
│ └── inflections.rb
├── environment.rb
├── boot.rb
├── application.example.yml
├── unicorn.rb
├── database.example.yml
├── routes.rb
├── environments
│ ├── development.rb
│ ├── test.rb
│ └── production.rb
└── application.rb
├── spec
├── controllers
│ ├── pages_controller_spec.rb
│ ├── searches_controller_spec.rb
│ ├── sessions_controller_spec.rb
│ ├── comments_controller_spec.rb
│ ├── authentications_controller_spec.rb
│ ├── users_controller_spec.rb
│ └── items_controller_spec.rb
├── factories
│ ├── comment.rb
│ ├── item.rb
│ ├── authentication.rb
│ └── user.rb
├── models
│ ├── search_spec.rb
│ ├── comment_spec.rb
│ ├── authentication_spec.rb
│ ├── item_spec.rb
│ └── user_spec.rb
├── helpers
│ ├── items_helper_spec.rb
│ ├── pages_helper_spec.rb
│ ├── users_helper_spec.rb
│ ├── comments_helper_spec.rb
│ ├── searches_helper_spec.rb
│ ├── sessions_helper_spec.rb
│ └── authentications_helper_spec.rb
└── spec_helper.rb
├── config.ru
├── doc
└── README_FOR_APP
├── Rakefile
├── script
└── rails
├── README.md
├── db
├── seeds.rb
└── migrate
│ ├── 20101220184946_create_users.rb
│ ├── 20101220185034_create_authentications.rb
│ ├── 20101225114202_create_items.rb
│ └── 20110107071143_create_comments.rb
├── .gitignore
├── Gemfile
├── LICENSE
└── Gemfile.lock
/lib/tasks/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --colour
2 |
--------------------------------------------------------------------------------
/vendor/plugins/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/helpers/items_helper.rb:
--------------------------------------------------------------------------------
1 | module ItemsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/pages_helper.rb:
--------------------------------------------------------------------------------
1 | module PagesHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/users_helper.rb:
--------------------------------------------------------------------------------
1 | module UsersHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/comments_helper.rb:
--------------------------------------------------------------------------------
1 | module CommentsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/searches_helper.rb:
--------------------------------------------------------------------------------
1 | module SearchesHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/sessions_helper.rb:
--------------------------------------------------------------------------------
1 | module SessionsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/app/helpers/authentications_helper.rb:
--------------------------------------------------------------------------------
1 | module AuthenticationsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/Procfile:
--------------------------------------------------------------------------------
1 | web: bundle exec unicorn config.ru -c config/unicorn.rb -p $PORT -E $RAILS_ENV
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/app/assets/images/feed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/feed.png
--------------------------------------------------------------------------------
/app/assets/images/guest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/guest.png
--------------------------------------------------------------------------------
/config/locales/searches.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | searches:
3 | index:
4 | title: "Результаты поиска"
--------------------------------------------------------------------------------
/app/assets/images/github_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/github_64.png
--------------------------------------------------------------------------------
/app/assets/images/hpc128x92.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/hpc128x92.png
--------------------------------------------------------------------------------
/app/assets/images/open_id_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/open_id_64.png
--------------------------------------------------------------------------------
/app/assets/images/twitter_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/twitter_64.png
--------------------------------------------------------------------------------
/config/initializers/bugsnag.rb:
--------------------------------------------------------------------------------
1 | Bugsnag.configure do |config|
2 | config.api_key = ENV['BUGSNAG_API_KEY']
3 | end
--------------------------------------------------------------------------------
/app/assets/images/icon-sprite.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/icon-sprite.png
--------------------------------------------------------------------------------
/app/assets/images/wmd-buttons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/wmd-buttons.png
--------------------------------------------------------------------------------
/spec/controllers/pages_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe PagesController do
4 |
5 | end
6 |
--------------------------------------------------------------------------------
/app/assets/images/railsclub128x92.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/railsclub128x92.png
--------------------------------------------------------------------------------
/app/assets/images/travis-ci50x50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/travis-ci50x50.png
--------------------------------------------------------------------------------
/app/assets/images/iosonrails120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/iosonrails120x120.png
--------------------------------------------------------------------------------
/config/locales/comments.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | comments:
3 | new:
4 | create: "Добавить"
5 | processing: "Сохранение..."
--------------------------------------------------------------------------------
/app/assets/images/digitalocean-badge-gray.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/app/assets/images/digitalocean-badge-gray.png
--------------------------------------------------------------------------------
/public/markdown-reference/images/arrow_down.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/public/markdown-reference/images/arrow_down.gif
--------------------------------------------------------------------------------
/public/markdown-reference/images/arrow_right.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/soulim/rbflow/HEAD/public/markdown-reference/images/arrow_right.gif
--------------------------------------------------------------------------------
/spec/factories/comment.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :comment do
3 | item
4 | user
5 | markdown "**bar**"
6 | end
7 | end
--------------------------------------------------------------------------------
/spec/factories/item.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :item do
3 | user
4 | title "foo"
5 | markdown "**bar**"
6 | end
7 | end
--------------------------------------------------------------------------------
/config/locales/authentications.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | authentications:
3 | destroy:
4 | successful: "Провайдер удален, но его всегда можно добавить обратно"
--------------------------------------------------------------------------------
/app/views/comments/_preview.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
<%=raw comment.html %>
4 |
5 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Rbflow::Application
5 |
--------------------------------------------------------------------------------
/spec/factories/authentication.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :authentication do
3 | user
4 | sequence(:uid) { |n| "foo-#{n}" }
5 | provider "foo"
6 | end
7 | end
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the rails application
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the rails application
5 | Rbflow::Application.initialize!
6 |
--------------------------------------------------------------------------------
/config/locales/pagination.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | views:
3 | pagination:
4 | first: "«"
5 | last: "»"
6 | previous: "←"
7 | next: "→"
8 | truncate: "..."
--------------------------------------------------------------------------------
/app/views/items/_preview.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
<%= item.title %>
4 |
<%=raw item.html %>
5 |
6 |
--------------------------------------------------------------------------------
/app/models/search.rb:
--------------------------------------------------------------------------------
1 | class Search
2 | def initialize(resource = Item)
3 | @resource = resource
4 | end
5 |
6 | def perform(query = '')
7 | @resource.basic_search(:html => query)
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | # Set up gems listed in the Gemfile.
4 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5 |
6 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
7 |
--------------------------------------------------------------------------------
/doc/README_FOR_APP:
--------------------------------------------------------------------------------
1 | Use this README file to introduce your application and point to useful places in the API for learning more.
2 | Run "rake doc:app" to generate API documentation for your models, controllers, helpers, and libraries.
3 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file
2 | #
3 | # To ban all spiders from the entire site uncomment the next two lines:
4 | # User-Agent: *
5 | # Disallow: /
6 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/app/controllers/sessions_controller.rb:
--------------------------------------------------------------------------------
1 | class SessionsController < ApplicationController
2 | def new; end
3 |
4 | def destroy
5 | session[:user_id] = nil
6 | redirect_to root_url, :notice => t("sessions.destroy.successful")
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
1 | //= require jquery
2 | //= require jquery_ujs
3 | //= require jquery.flash
4 | //= require highlight.pack
5 | //= require wmd.combined.min
6 |
7 | $(document).ready(function() {
8 | $.flash(); // toggle flash messages
9 | });
--------------------------------------------------------------------------------
/app/controllers/pages_controller.rb:
--------------------------------------------------------------------------------
1 | class PagesController < ApplicationController
2 | respond_to :html
3 |
4 | def show
5 | @page = params[:id]
6 | render(:layout => false, :file => "public/404.html", :status => :not_found) unless %w(about).include?(@page)
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/controllers/searches_controller.rb:
--------------------------------------------------------------------------------
1 | class SearchesController < ApplicationController
2 | respond_to :html
3 |
4 | def index
5 | @search = Search.new(Item)
6 | respond_with @items = @search.perform(params[:q]).page(params[:page]).per(20)
7 | end
8 |
9 | end
10 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 | require 'rake'
6 |
7 | Rbflow::Application.load_tasks
8 |
--------------------------------------------------------------------------------
/app/views/comments/_comment.html.erb:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/config/initializers/action_mailer.rb:
--------------------------------------------------------------------------------
1 | ActionMailer::Base.smtp_settings = {
2 | :address => ENV['SMTP_ADDRESS'],
3 | :port => ENV['SMTP_PORT'],
4 | :user_name => ENV['SMTP_USERNAME'],
5 | :password => ENV['SMTP_PASSWORD']
6 | }
7 | ActionMailer::Base.default_url_options[:host] = ENV['SMTP_HOST']
8 |
--------------------------------------------------------------------------------
/config/application.example.yml:
--------------------------------------------------------------------------------
1 | # Add application configuration variables here, as shown below.
2 | #
3 | # PUSHER_APP_ID: "2954"
4 | # PUSHER_KEY: 7381a978f7dd7f9a1117
5 | # PUSHER_SECRET: abdc3b896a0ffb85d373
6 | # STRIPE_API_KEY: EdAvEPVEC3LuaTg5Q3z6WbDVqZlcBQ8Z
7 | # STRIPE_PUBLIC_KEY: pk_BRgD57O8fHja9HxduJUszhef6jCyS
8 |
--------------------------------------------------------------------------------
/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/config/initializers/omniauth.rb:
--------------------------------------------------------------------------------
1 | require 'openid/store/filesystem'
2 |
3 | Rails.application.config.middleware.use OmniAuth::Builder do
4 | provider :twitter, ENV['TWITTER_KEY'], ENV['TWITTER_SECRET']
5 | provider :github, ENV['GITHUB_KEY'], ENV['GITHUB_SECRET']
6 | provider :openid, :store => OpenID::Store::Filesystem.new('/tmp')
7 | end
--------------------------------------------------------------------------------
/config/locales/users.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | users:
3 | index:
4 | title: "Авторы"
5 | approve: "Доверять"
6 | unapprove: "Не доверять"
7 | destroy: "Удалить"
8 | show:
9 | title: "Аккаунт"
10 | providers: "Провайдеры аутентификации"
11 | add_provider: "Добавить"
12 | remove_provider: "Удалить"
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RbFlow
2 |
3 | ## Descripton
4 |
5 | RbFlow is community blog engine which works behind rubyflow.ru
6 |
7 | ## Resources
8 |
9 | * Issue tracker -- [github.com/soulim/rbflow/issues](https://github.com/soulim/rbflow/issues)
10 |
11 | ## License
12 |
13 | See the file LICENSE
14 |
15 | Copyright (c) 2010-2016, Alexander Sulim
16 |
--------------------------------------------------------------------------------
/app/controllers/comments_controller.rb:
--------------------------------------------------------------------------------
1 | class CommentsController < ApplicationController
2 | load_and_authorize_resource :item
3 | load_and_authorize_resource :comment, :through => :item
4 |
5 | respond_to :js
6 |
7 | def create
8 | @comment.user = current_user
9 | respond_with(@item, @comment.save)
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/app/views/pages/show.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, t(".#{@page}.title") %>
2 |
3 |
6 |
7 | <%= t(".#{@page}.title") %>
8 | <%= RDiscount.new(t(".#{@page}.markdown")).to_html.html_safe %>
9 |
10 |
--------------------------------------------------------------------------------
/config/locales/cancan.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | unauthorized:
3 | manage:
4 | all: "Неа, нужно быть админом!"
5 | create:
6 | all: "Сначала авторизуйтесь!"
7 | update:
8 | user: "Можно редактировать только свой аккаунт!"
9 | item: "Нет доступа, потому что вы не автор статьи!"
10 | destroy:
11 | all: "Неа, нужно быть админом!"
12 |
--------------------------------------------------------------------------------
/spec/controllers/searches_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SearchesController do
4 | let(:result) { Kaminari.paginate_array([]) }
5 |
6 | describe "GET index" do
7 | it "performs search for some items" do
8 | Search.any_instance.should_receive(:perform).and_return(result)
9 | get :index
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/factories/user.rb:
--------------------------------------------------------------------------------
1 | FactoryGirl.define do
2 | factory :user do
3 | name "John 'user' Doe"
4 | email "user@example.com"
5 | avatar_url ""
6 | role 0
7 | end
8 |
9 | factory :admin do
10 | name "John 'user' Doe"
11 | email "user@example.com"
12 | avatar_url ""
13 | role 1
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/spec/models/search_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Search do
4 | let(:resource) { double('resource') }
5 |
6 | subject { Search.new(resource) }
7 |
8 | describe '#find' do
9 | it 'should perform basic search on resource' do
10 | resource.should_receive(:basic_search)
11 |
12 | subject.perform('foo')
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | # This file should contain all the record creation needed to seed the database with its default values.
2 | # The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
3 | #
4 | # Examples:
5 | #
6 | # cities = City.create([{ :name => 'Chicago' }, { :name => 'Copenhagen' }])
7 | # Mayor.create(:name => 'Daley', :city => cities.first)
8 |
--------------------------------------------------------------------------------
/app/views/comments/_form.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | <%= f.text_area :markdown, :placeholder => t("activerecord.attributes.comment.markdown"), :rows => 10, :autofocus => true %>
4 |
5 | <% content_for :footer_js do %>
6 |
11 | <% end %>
--------------------------------------------------------------------------------
/config/unicorn.rb:
--------------------------------------------------------------------------------
1 | listen '/tmp/unicorn.rubyflow.sock'
2 | worker_processes 4
3 | timeout 30
4 | preload_app true
5 |
6 | before_fork do |server, worker|
7 | defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
8 | end
9 |
10 | after_fork do |server, worker|
11 | defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
12 | end
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle
2 | .DS_Store
3 | .ruby-version
4 | .env
5 | db/*.sqlite3
6 | db/schema.rb
7 | db/sphinx/**/*
8 | log/*.log
9 | log/*.pid
10 | tmp/**/*
11 | config/database.yml
12 | config/omniauth.yml
13 | config/mail.yml
14 | config/newrelic.yml
15 | config/thinking_sphinx.yml
16 | config/deploy.rb
17 | config/deploy
18 | config/*.sphinx.conf
19 |
20 | # Ignore application configuration
21 | /config/application.yml
22 |
--------------------------------------------------------------------------------
/config/locales/sessions.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | sessions:
3 | new:
4 | choose_provider: "Выберите провайдера:"
5 | description: |
6 | ## Нужно дополнить список?
7 |
8 | Можно добавить любого провайдера, которого поддерживает [OmniAuth](https://github.com/intridea/omniauth). Напишите мне на [soulim@gmail.com](mailto:soulim@gmail.com)
9 | destroy:
10 | successful: "Удачи желаю! :)"
--------------------------------------------------------------------------------
/app/models/comment.rb:
--------------------------------------------------------------------------------
1 | class Comment < ActiveRecord::Base
2 | belongs_to :item
3 | belongs_to :user
4 |
5 | validates_presence_of :item_id, :user_id, :markdown
6 |
7 | attr_accessible :markdown
8 |
9 | before_save :assign_html, :if => :markdown?
10 |
11 | private
12 |
13 | def assign_html
14 | self.html = RDiscount.new(self.markdown, :filter_styles, :filter_html, :autolink).to_html
15 | end
16 | end
--------------------------------------------------------------------------------
/public/markdown-reference/javascripts/guide.js:
--------------------------------------------------------------------------------
1 | $(window).ready(function() {
2 | $('.section-name').each(function(i) {
3 | if(i > 0){
4 | toggleSection(i);
5 | }
6 |
7 | $(this).click(function() {
8 | toggleSection(i)
9 | });
10 | });
11 | });
12 |
13 | function toggleSection(i) {
14 | $('.section').slice(i, i + 1).toggle();
15 | $('.section-name').slice(i, i + 1).toggleClass('deselected');
16 | }
--------------------------------------------------------------------------------
/db/migrate/20101220184946_create_users.rb:
--------------------------------------------------------------------------------
1 | class CreateUsers < ActiveRecord::Migration
2 | def self.up
3 | create_table :users do |t|
4 | t.string :name
5 | t.string :email
6 | t.string :avatar_url
7 | t.integer :role, :default => 0, :null => false
8 | t.datetime :approved_at
9 |
10 | t.timestamps
11 | end
12 | end
13 |
14 | def self.down
15 | drop_table :users
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Rbflow::Application.config.session_store :cookie_store, key: '_rbflow_session'
4 |
5 | # Use the database for sessions instead of the cookie-based default,
6 | # which shouldn't be used to store highly confidential information
7 | # (create the session table with "rails generate session_migration")
8 | # Rbflow::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/spec/controllers/sessions_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe SessionsController do
4 | before { session[:user_id] = 1 }
5 |
6 | describe "DELETE destroy" do
7 | it "drops user's session" do
8 | delete :destroy
9 | session[:user_id].should be_nil
10 | end
11 |
12 | it "redirects to home url" do
13 | delete :destroy
14 | response.should redirect_to(root_url)
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/views/comments/_new.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= render :partial => "comments/preview", :locals => { :comment => comment } %>
3 |
4 |
--------------------------------------------------------------------------------
/db/migrate/20101220185034_create_authentications.rb:
--------------------------------------------------------------------------------
1 | class CreateAuthentications < ActiveRecord::Migration
2 | def self.up
3 | create_table :authentications do |t|
4 | t.integer :user_id
5 | t.string :provider
6 | t.string :uid
7 |
8 | t.timestamps
9 | end
10 |
11 | add_index :authentications, [:uid, :provider], :uniq => true
12 | end
13 |
14 | def self.down
15 | drop_table :authentications
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/views/sessions/new.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= t(".choose_provider") %>
3 |
4 | <% for provider in Authentication::PROVIDERS.keys %>
5 | <%= link_to "#{image_tag("#{provider}_64.png", :size => "64x64")} #{Authentication::PROVIDERS[provider]}".html_safe, "/auth/#{provider}" %>
6 | <% end %>
7 |
8 |
9 |
10 | <%= markdown t(".description") %>
11 |
--------------------------------------------------------------------------------
/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 | # Make sure the secret is at least 30 characters and all random,
6 | # no regular words or you'll be exposed to dictionary attacks.
7 | Rbflow::Application.config.secret_token = ENV['SESSION_SECRET'] || 'afake32charactertokenfortesting'
8 |
--------------------------------------------------------------------------------
/db/migrate/20101225114202_create_items.rb:
--------------------------------------------------------------------------------
1 | class CreateItems < ActiveRecord::Migration
2 | def self.up
3 | create_table :items do |t|
4 | t.belongs_to :user
5 | t.string :title
6 | t.text :markdown
7 | t.text :html
8 |
9 | t.timestamps
10 | end
11 |
12 | add_index :items, :created_at
13 | add_index :items, :user_id
14 | end
15 |
16 | def self.down
17 | drop_table :items
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/db/migrate/20110107071143_create_comments.rb:
--------------------------------------------------------------------------------
1 | class CreateComments < ActiveRecord::Migration
2 | def self.up
3 | create_table :comments do |t|
4 | t.belongs_to :item
5 | t.belongs_to :user
6 | t.text :markdown
7 | t.text :html
8 | t.timestamps
9 | end
10 |
11 | add_index :comments, :item_id
12 | add_index :comments, :user_id
13 | end
14 |
15 | def self.down
16 | drop_table :comments
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/spec/helpers/items_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the ItemsHelper. For example:
5 | #
6 | # describe ItemsHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe ItemsHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/pages_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the PagesHelper. For example:
5 | #
6 | # describe PagesHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe PagesHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/users_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the UsersHelper. For example:
5 | #
6 | # describe UsersHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe UsersHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/comments_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the CommentsHelper. For example:
5 | #
6 | # describe CommentsHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe CommentsHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/searches_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the SearchesHelper. For example:
5 | #
6 | # describe SearchesHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe SearchesHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/spec/helpers/sessions_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the SessionsHelper. For example:
5 | #
6 | # describe SessionsHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe SessionsHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/app/views/comments/create.js.erb:
--------------------------------------------------------------------------------
1 | <% if @comment.errors.any? %>
2 | $('#item-<%= @item.id %>-new-comment').html('<%= escape_javascript render(:partial => "comments/new", :locals => { :item => @item, :comment => @comment }) %>');
3 | <% else %>
4 | $('#item-<%= @item.id %>-new-comment').before('<%= escape_javascript render(@comment)%>');
5 | $('#item-<%= @item.id %>-new-comment').html('<%= escape_javascript render(:partial => "comments/new", :locals => { :item => @item, :comment => @item.comments.new }) %>');
6 | <% end %>
--------------------------------------------------------------------------------
/app/views/items/edit.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, t(".title") %>
2 |
3 |
4 | <%= render :partial => "preview", :locals => { :item => @item } %>
5 |
6 |
15 |
16 |
--------------------------------------------------------------------------------
/app/views/items/new.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, t(".title") %>
2 |
3 |
4 | <%= render :partial => "preview", :locals => { :item => @item } %>
5 |
6 |
15 |
16 |
--------------------------------------------------------------------------------
/spec/helpers/authentications_helper_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | # Specs in this file have access to a helper object that includes
4 | # the AuthenticationsHelper. For example:
5 | #
6 | # describe AuthenticationsHelper do
7 | # describe "string concat" do
8 | # it "concats two strings with spaces" do
9 | # helper.concat_strings("this","that").should == "this that"
10 | # end
11 | # end
12 | # end
13 | describe AuthenticationsHelper do
14 | pending "add some examples to (or delete) #{__FILE__}"
15 | end
16 |
--------------------------------------------------------------------------------
/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 | #
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json]
9 | end
10 |
11 | # Disable root element in JSON by default.
12 | ActiveSupport.on_load(:active_record) do
13 | self.include_root_in_json = false
14 | end
15 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format
4 | # (all these examples are active by default):
5 | # ActiveSupport::Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 | #
12 | # These inflection rules are supported but not enabled by default:
13 | # ActiveSupport::Inflector.inflections do |inflect|
14 | # inflect.acronym 'RESTful'
15 | # end
16 |
--------------------------------------------------------------------------------
/app/views/items/index.rss.builder:
--------------------------------------------------------------------------------
1 | xml.instruct! :xml, :version => "1.0"
2 | xml.rss :version => "2.0" do
3 | xml.channel do
4 | xml.title t("layouts.application.title")
5 | xml.description t("layouts.application.meta_description")
6 | xml.link items_url
7 | xml.language('ru-ru')
8 |
9 | for item in @items.select{ |item| item.user.approved? }
10 | xml.item do
11 | xml.title item.title
12 | xml.description item.html
13 | xml.pubDate item.created_at.to_s(:rfc822)
14 | xml.link item_url(item)
15 | xml.guid item_url(item)
16 | end
17 | end
18 | end
19 | end
--------------------------------------------------------------------------------
/app/controllers/users_controller.rb:
--------------------------------------------------------------------------------
1 | class UsersController < ApplicationController
2 | load_and_authorize_resource
3 |
4 | respond_to :html
5 |
6 | def index
7 | respond_with(@users = User.order("created_at DESC").page(params[:page]).per(20))
8 | end
9 |
10 | def show
11 | respond_with(@user = current_user)
12 | end
13 |
14 | def approve
15 | respond_with(@user.approve!, :location => users_url)
16 | end
17 |
18 | def unapprove
19 | respond_with(@user.unapprove!, :location => users_url)
20 | end
21 |
22 | def destroy
23 | respond_with(@user.destroy)
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/app/views/items/_form.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= f.text_field :title, :placeholder => t("activerecord.attributes.item.title"), :autofocus => true %>
3 |
4 |
5 |
6 | <%= f.text_area :markdown, :placeholder => t("activerecord.attributes.item.markdown") %>
7 |
8 | <% content_for :footer_js do %>
9 |
20 | <% end %>
21 |
--------------------------------------------------------------------------------
/config/database.example.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3-ruby (not necessary on OS X Leopard)
3 | development:
4 | adapter: sqlite3
5 | database: db/development.sqlite3
6 | pool: 5
7 | timeout: 5000
8 |
9 | # Warning: The database defined as "test" will be erased and
10 | # re-generated from your development database when you run "rake".
11 | # Do not set this db to the same as development or production.
12 | test:
13 | adapter: sqlite3
14 | database: db/test.sqlite3
15 | pool: 5
16 | timeout: 5000
17 |
18 | production:
19 | adapter: sqlite3
20 | database: db/production.sqlite3
21 | pool: 5
22 | timeout: 5000
23 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/icon.css:
--------------------------------------------------------------------------------
1 | .icon {
2 | display:inline-block;
3 | vertical-align:middle;
4 | width:16px;
5 | height:16px;
6 | background:transparent url(/assets/icon-sprite.png) 0 0 no-repeat;
7 | }
8 | .item-edit { background-position:0 0; }
9 | .item-remove { background-position:-16px 0; }
10 | .comment-add { background-position:-0px 0; }
11 | .comment-edit { background-position:-48px 0; }
12 | .comment-remove { background-position:-64px 0; }
13 | .user-accept { background-position:-80px 0; }
14 | .user-cancel { background-position:-96px 0; }
15 | .user-edit { background-position:-112px 0; }
16 | .user-remove { background-position:-128px 0; }
--------------------------------------------------------------------------------
/app/views/searches/index.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, t(".title") %>
2 |
3 |
4 | <%= t(".title") %>
5 | <%= @items.total_count %>
6 |
7 |
8 | <% for item in @items do %>
9 |
10 |
11 | <%= link_to item.title, item %><%= item.user.name %>
12 |
13 | <%= item.html.html_safe %>
14 |
15 | <% end %>
16 | <%= paginate @items %>
17 |
18 |
21 |
22 |
--------------------------------------------------------------------------------
/config/locales/layouts.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | layouts:
3 | application:
4 | meta_description: "Коллективный блог сообщества разработчиков, использующих Ruby"
5 | meta_keywords: "Ruby,JRuby,Rails,Sinatra,Rails3,Authlogic"
6 | meta_author: ""
7 | title: "RubyFlow.ru"
8 | new_item: "Добавить статью"
9 | vacancies: "Вакансии"
10 | account: "Аккаунт"
11 | search: "Поиск"
12 | sign_in: "Вход"
13 | sign_out: "Выход"
14 | about: "О проекте"
15 | terms: "Условия"
16 | users: "Пользователи"
17 | contacts: "Контактная информация"
18 | commons:
19 | destroy_confirmation: "Действительно удалить '%{subject}'?"
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rbflow::Application.routes.draw do
2 | get "searches/index"
3 |
4 | match '/auth/:provider/callback', :to => 'authentications#create'
5 | match '/sign_in', :to => 'sessions#new'
6 | match '/sign_out', :to => 'sessions#destroy'
7 |
8 | resources :sessions, :only => [ :new, :destroy ]
9 | resources :pages, :only => :show
10 | resources :searches, :only => :index
11 | resources :users do
12 | member do
13 | put 'approve'
14 | put 'unapprove'
15 | end
16 | resources :authentications, :only => :destroy
17 | end
18 | resources :items do
19 | resources :comments
20 | end
21 |
22 | root :to => "items#index"
23 | end
24 |
--------------------------------------------------------------------------------
/app/models/ability.rb:
--------------------------------------------------------------------------------
1 | class Ability
2 | include CanCan::Ability
3 |
4 | def initialize(user)
5 | user ||= User.new # guest user
6 |
7 | if user.admin?
8 | can :manage, :all
9 | else
10 | can :read, Item
11 |
12 | if !user.guest?
13 | can(:update, Item) { |item| item.author?(user) && item.created_at.today? }
14 | can(:destroy, Item) { |item| item.author?(user) && item.created_at.today? }
15 | can(:create, [Item, Comment])
16 | can(:show, User) { |_user| _user.me?(user) }
17 | can(:destroy, Authentication) { |authentication| authentication.user_id == user.id && user.authentications.size > 1 }
18 | end
19 | end
20 | end
21 | end
--------------------------------------------------------------------------------
/app/models/item.rb:
--------------------------------------------------------------------------------
1 | class Item < ActiveRecord::Base
2 | belongs_to :user
3 | has_many :comments, :dependent => :destroy
4 |
5 | validates_presence_of :title, :markdown
6 | validates_presence_of :user_id, :on => :create
7 |
8 | attr_accessible :title, :markdown
9 |
10 | before_save :assign_html, :if => :markdown?
11 |
12 | scope :recent, includes(:user).order("created_at desc")
13 |
14 | def author?(user)
15 | self.user_id == user.id
16 | end
17 |
18 | def author_name
19 | self.user.blank? ? "" : self.user.name
20 | end
21 |
22 | private
23 |
24 | def assign_html
25 | self.html = RDiscount.new(self.markdown, :filter_styles, :filter_html, :autolink).to_html
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/models/authentication.rb:
--------------------------------------------------------------------------------
1 | class Authentication < ActiveRecord::Base
2 | PROVIDERS = {
3 | "open_id" => "OpenID",
4 | "github" => "GitHub",
5 | "twitter" => "Twitter"
6 | }
7 |
8 | belongs_to :user
9 |
10 | validates_presence_of :user_id, :uid, :provider
11 | validates_uniqueness_of :uid, :scope => :provider
12 |
13 | def self.create_with_omniauth!(auth, user = nil)
14 | user ||= User.create_with_omniauth!(auth)
15 | self.create! do |authentication|
16 | authentication.user = user
17 | authentication.uid = auth['uid']
18 | authentication.provider = auth['provider']
19 | end
20 | end
21 |
22 | def provider_name
23 | PROVIDERS[self.provider]
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/app/controllers/authentications_controller.rb:
--------------------------------------------------------------------------------
1 | class AuthenticationsController < ApplicationController
2 | load_and_authorize_resource :only => :destroy
3 |
4 | respond_to :html
5 |
6 | def new; end
7 |
8 | def create
9 | auth = request.env['omniauth.auth']
10 |
11 | unless @auth = Authentication.find_by_provider_and_uid(auth["provider"], auth["uid"])
12 | @auth = Authentication.create_with_omniauth!(auth, current_user)
13 | end
14 | self.current_user = @auth.user
15 |
16 | respond_with(@auth) do |format|
17 | format.html { redirect_back_or_default root_url }
18 | end
19 | end
20 |
21 | def destroy
22 | @authentication.destroy and flash[:notice] = t("authentications.destroy.successful")
23 | respond_with(@authentication, :location => user_url(current_user))
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/models/comment_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Comment do
4 | subject { FactoryGirl.build(:comment) }
5 |
6 | it "is valid with valid attributes" do
7 | subject.should be_valid
8 | end
9 |
10 | it "is not valid without user" do
11 | subject.user = nil
12 | subject.should_not be_valid
13 | end
14 |
15 | it "is not valid without item" do
16 | subject.item = nil
17 | subject.should_not be_valid
18 | end
19 |
20 | it "is not valid without markdown" do
21 | subject.markdown = nil
22 | subject.should_not be_valid
23 | end
24 |
25 | context "before save" do
26 | before { subject.save! }
27 |
28 | it "convert markdown to HTML" do
29 | subject.html.should include("")
30 | end
31 |
32 | it "assigns html" do
33 | subject.html.should_not be_blank
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/config/locales/items.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | items:
3 | index:
4 | title: "Коллективный блог сообщества разработчиков, использующих Ruby"
5 | comments: "Комментарии"
6 | new:
7 | title: "Новая статья"
8 | create: "Опубликовать"
9 | cancel: "Отмена"
10 | processing: "Сохранение..."
11 | create:
12 | successful: "Статья добавлена"
13 | edit:
14 | title: "Редактирование статьи"
15 | update: "Обновить"
16 | cancel: "Отмена"
17 | processing: "Сохранение..."
18 | update:
19 | successful: "Статья обновлена"
20 | show:
21 | edit: "Редактировать"
22 | destroy: "Удалить"
23 | comments: "Комментарии"
24 | new_comment: "Добавить свое мнение"
25 | please_sign_in_to_add_comment: "Пожалуйста авторизуйтесь, чтобы добавить комментарий."
26 | destroy:
27 | successful: "Статья удалена"
28 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | gem "rails", "~> 3.2.13"
4 |
5 | gem "jquery-rails", "~> 2.2.1"
6 | gem "omniauth", "~> 1.1.4"
7 | gem "omniauth-openid", "~> 1.0.1"
8 | gem "omniauth-twitter", "~> 0.0.16"
9 | gem "omniauth-github", "~> 1.1.0"
10 | gem "cancan", "~> 1.6.9"
11 | gem "rdiscount", "~> 2.0.7.2"
12 | gem "kaminari", "~> 0.14.1"
13 | gem "pg", "~> 0.15.1"
14 | gem "textacular", "~> 3.0.0", require: "textacular/rails"
15 | gem "foreman", "~> 0.63.0"
16 | gem "unicorn", "~> 4.6.2"
17 | gem "bugsnag", "~> 1.3.6"
18 | gem "figaro", "~> 0.6.4"
19 |
20 | group :assets do
21 | gem "therubyracer", "~> 0.12.2"
22 | gem "uglifier", "~> 2.0.1"
23 | end
24 |
25 | group :development, :test do
26 | gem "rspec-rails", "~> 2.13.1"
27 | gem "mina", :git => "git://github.com/nadarei/mina.git"
28 | end
29 |
30 | group :test do
31 | gem "factory_girl_rails", "~> 4.2.1"
32 | end
33 |
34 | group :production do
35 | gem "newrelic_rpm", "~> 3.6.1.88"
36 | end
37 |
--------------------------------------------------------------------------------
/app/controllers/items_controller.rb:
--------------------------------------------------------------------------------
1 | class ItemsController < ApplicationController
2 | load_and_authorize_resource
3 |
4 | respond_to :html
5 | respond_to :rss, :only => :index
6 |
7 | def index
8 | respond_with(@items = Item.recent.page(params[:page]).per(10))
9 | end
10 |
11 | def new
12 | respond_with(@item = current_user.items.new)
13 | end
14 |
15 | def create
16 | @item = current_user.items.create(params[:item]) and flash[:notice] = t("items.create.successful")
17 | respond_with(@item)
18 | end
19 |
20 | def show
21 | respond_with(@item)
22 | end
23 |
24 | def edit
25 | respond_with(@item)
26 | end
27 |
28 | def update
29 | @item.update_attributes(params[:item]) and flash[:notice] = t("items.update.successful")
30 | respond_with(@item)
31 | end
32 |
33 | def destroy
34 | @item.destroy and flash[:notice] = t("items.destroy.successful")
35 | respond_with(@item)
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | protect_from_forgery
3 |
4 | helper_method :current_user, :signed_in?
5 |
6 | protected
7 |
8 | def current_user
9 | @current_user ||= User.find_by_id(session[:user_id]) if session[:user_id]
10 | end
11 |
12 | def signed_in?
13 | !!current_user
14 | end
15 |
16 | def current_user=(user)
17 | @current_user = user
18 | session[:user_id] = user.id
19 | end
20 |
21 | def store_location
22 | session[:return_to] = request.fullpath
23 | end
24 |
25 | def redirect_back_or_default(default)
26 | redirect_to back_or_default_path(default)
27 | session[:return_to] = nil
28 | end
29 |
30 | def back_or_default_path(default)
31 | session[:return_to] || default
32 | end
33 |
34 | rescue_from CanCan::AccessDenied do |exception|
35 | store_location
36 | redirect_to sign_in_path, :notice => exception.message
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/app/views/users/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= t(".title") %>
3 |
4 |
5 |
6 | <% for user in @users %>
7 |
8 | <%= image_tag avatar_url(user), :size => "48x48", :alt => user.name, :class => "avatar" %>
9 |
10 | <%= user.name %>
11 | <%= mail_to user.email, nil, :encode => "hex" %>
12 |
13 |
14 | <%= (user.approved?) ? link_to(t(".unapprove"), unapprove_user_url(user), :method => :put, :class => "small button") : link_to(t(".approve"), approve_user_url(user), :method => :put, :class => "small button") %>
15 | <%= link_to t(".destroy"), user, :method => :delete, :confirm => t("layouts.commons.destroy_confirmation", :subject => user.name), :class => "small button" %>
16 |
17 |
18 | <% end %>
19 |
20 | <%= paginate @users %>
21 |
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < ActiveRecord::Base
2 | ROLES = {
3 | :user => 0,
4 | :admin => 1
5 | }
6 | ROLES.each_pair {|role, code| define_method("#{role}?") { self.role == code } }
7 |
8 | has_many :authentications, :dependent => :destroy
9 | has_many :items, :dependent => :nullify
10 | has_many :comments, :dependent => :destroy
11 |
12 | attr_protected :role
13 |
14 | def self.create_with_omniauth!(auth)
15 | self.create! do |user|
16 | user.name = auth["info"]["name"]
17 | user.email = auth["info"]["email"]
18 | user.avatar_url = auth["info"]["image"]
19 | end
20 | end
21 |
22 | def approved?
23 | !self.approved_at.nil?
24 | end
25 |
26 | def approve!
27 | self.update_attributes(:approved_at => Time.zone.now)
28 | self
29 | end
30 |
31 | def unapprove!
32 | self.update_attributes(:approved_at => nil)
33 | self
34 | end
35 |
36 | def guest?
37 | self.new_record?
38 | end
39 |
40 | def me?(user)
41 | self.id == user.id
42 | end
43 |
44 | def providers
45 | self.authentications.collect(&:provider)
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/public/markdown-reference/LICENCE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008 Pete Nicholls
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
24 |
--------------------------------------------------------------------------------
/spec/models/authentication_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Authentication do
4 | subject { FactoryGirl.build(:authentication) }
5 |
6 | it "is valid with valid attributes" do
7 | subject.should be_valid
8 | end
9 |
10 | it "is not valid without user" do
11 | subject.user = nil
12 | subject.should_not be_valid
13 | end
14 |
15 | it "is not valid without uid" do
16 | subject.uid = nil
17 | subject.should_not be_valid
18 | end
19 |
20 | it "is not valid without provider" do
21 | subject.provider = nil
22 | subject.should_not be_valid
23 | end
24 |
25 | it "is not valid without uniq uid scoped to provider" do
26 | other_authentication = FactoryGirl.create(:authentication, :uid => subject.uid, :provider => subject.provider)
27 | subject.should_not be_valid
28 | end
29 |
30 | describe ".create_with_omniauth" do
31 | it "creates a new authentication based on given params"
32 | end
33 |
34 | describe "#provider_name" do
35 | it "returns titleized provider name" do
36 | subject.provider_name.should == Authentication::PROVIDERS[subject.provider]
37 | end
38 | end
39 | end
40 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | # Flash messages as html
3 | def flash_messages(messages = {})
4 | messages = flash unless flash.empty?
5 | messages.collect{ |kind, message| flash_message(message, kind) }.join.html_safe
6 | end
7 |
8 | def flash_message(message, kind = :notice)
9 | content_tag :div, message, :class => "message #{kind.to_s}"
10 | end
11 |
12 | def markdown(source)
13 | source.blank? ? "" : RDiscount.new(source).to_html.html_safe
14 | end
15 |
16 | def avatar_url(user)
17 | if user.avatar_url.present?
18 | user.avatar_url
19 | else
20 | default_url = "#{root_url}images/guest.png"
21 | if !user.email.blank?
22 | gravatar_id = Digest::MD5::hexdigest(user.email).downcase
23 | "http://gravatar.com/avatar/#{gravatar_id}.png?s=48&d=#{CGI.escape(default_url)}"
24 | else
25 | default_url
26 | end
27 | end
28 | end
29 |
30 | def icon_tag(icon)
31 | content_tag :i, nil, :class => "icon #{icon}"
32 | end
33 |
34 | def years_tag(from = 2008, to = Date.current.year)
35 | if from != to
36 | "#{from}—#{to}".html_safe
37 | else
38 | from.to_s
39 | end
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/config/locales/pages.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | pages:
3 | show:
4 | about:
5 | title: "Коллективный блог сообщества разработчиков"
6 | markdown: |
7 | На этом сайте публикуются статьи о языке Ruby и всем, что с ним связано.
8 |
9 | Концепцию RubyFlow создал Питер Купер ([Peter Cooper](http://peterc.org)), автор [Ruby Inside](http://www.rubyinside.com). Опубликованные материлы можно читать непосредственно на сайте, а также через [RSS](http://feedproxy.google.com/rubyflowru) или [Twitter](http://twitter.com/rubyflowru). Но в последние два источника статьи попадают только от проверенных временем авторов.
10 |
11 | Проект в эфире уже третий год и собрал более 1 000 статей.
12 |
13 | Данная версия RubyFlow.ru является проектом с открытым исходным кодом, который всегда можно найти на GitHub -- [github.com/soulim/rbflow](https://github.com/soulim/rbflow).
14 |
15 | Если у вас возникли вопросы, появились идеи или есть интересные предложения, то смело пишите. Постараюсь ответить в тот же день.
16 |
17 | Электронная почта: [soulim@gmail.com](mailto:soulim@gmail.com)
18 | Твиттер: [@rubyflowru](http://twitter.com/rubyflowru)
19 |
20 |
21 | *Александр Сулим,
22 | основатель и ведущий разработчик*
23 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/reset.css:
--------------------------------------------------------------------------------
1 | abbr,article,aside,audio,bb,canvas,datagrid,datalist,details,dialog,figure,footer,header,mark,menu,meter,nav,output,progress,section,time,video {
2 | display:block;
3 | }
4 | html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,
5 | blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,
6 | em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,
7 | tt,var,hr,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,
8 | label,legend {
9 | padding:0;
10 | margin:0;
11 | border:none;
12 | outline:none;
13 | vertical-align:baseline;
14 | }
15 | dfn,i,cite,var,address,em {
16 | font-style:normal;
17 | }
18 | th,b,strong,h1,h2,h3,h4,h5,h6{
19 | font-weight:normal;
20 | }
21 | textarea,input,select{
22 | font-family:inherit;
23 | font-size:1em;
24 | }
25 | blockquote,q {
26 | quotes:none;
27 | }
28 | q:before,q:after,
29 | blockquote:before,
30 | blockquote:after {
31 | content:'';
32 | content:none;
33 | }
34 | ol,ul {
35 | list-style:none;
36 | }
37 | ins {
38 | text-decoration:none;
39 | }
40 | del {
41 | text-decoration:line-through;
42 | }
43 | table {
44 | border-collapse:collapse;
45 | border-spacing:0;
46 | }
47 | caption,th,td {
48 | text-align:left;
49 | }
50 | :focus {
51 | outline:none;
52 | }
--------------------------------------------------------------------------------
/vendor/assets/javascripts/jquery.flash.js:
--------------------------------------------------------------------------------
1 | /*
2 | * jQuery Flash Message Plugin v0.0.1
3 | * http://textro.ws
4 | *
5 | * This document is licensed as free software under the terms of the
6 | * MIT License: http://www.opensource.org/licenses/mit-license.php
7 | *
8 | * Copyright (c) 2010 by Alex Soulim (soulim@gmail.com).
9 | */
10 |
11 | (function( $ ){
12 | var $this = $("#flash");
13 |
14 | var methods = {
15 | init: function () {
16 | if ( $this.html() != "" ) {
17 | $.flash("toggle");
18 | };
19 | },
20 | toggle: function () {
21 | $this.slideDown("slow").delay(4000).slideUp("fast");
22 | },
23 | notice: function ( message ) {
24 | $this.html($("
", { "class": "message notice", text: message }));
25 | $.flash("toggle");
26 | },
27 | error: function ( message ) {
28 | $this.html($("
", { "class": "message error", text: message }));
29 | $.flash("toggle");
30 | }
31 | };
32 |
33 | $.flash = function( method ) {
34 | if ( methods[method] ) {
35 | return methods[method].apply(this, Array.prototype.slice.call( arguments, 1 ));
36 | } else if ( typeof method === 'object' || ! method ) {
37 | return methods.init.apply(this, arguments);
38 | } else {
39 | $.error( 'Method ' + method + ' does not exist on jQuery.flash' );
40 | }
41 | };
42 | })( jQuery );
43 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # This file is copied to spec/ when you run 'rails generate rspec:install'
2 | ENV["RAILS_ENV"] ||= 'test'
3 | require File.expand_path("../../config/environment", __FILE__)
4 | require 'rspec/rails'
5 | require 'rspec/autorun'
6 |
7 | # Requires supporting ruby files with custom matchers and macros, etc,
8 | # in spec/support/ and its subdirectories.
9 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
10 |
11 | RSpec.configure do |config|
12 | # == Mock Framework
13 | #
14 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
15 | #
16 | # config.mock_with :mocha
17 | # config.mock_with :flexmock
18 | # config.mock_with :rr
19 | config.mock_with :rspec
20 |
21 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
22 | # config.fixture_path = "#{::Rails.root}/spec/fixtures"
23 |
24 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
25 | # examples within a transaction, remove the following line or assign false
26 | # instead of true.
27 | config.use_transactional_fixtures = true
28 |
29 | # If true, the base class of anonymous controllers will be inferred
30 | # automatically. This will be the default behavior in future versions of
31 | # rspec-rails.
32 | config.infer_base_class_for_anonymous_controllers = false
33 | end
34 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Rbflow::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Don't care if the mailer can't send
17 | config.action_mailer.raise_delivery_errors = false
18 |
19 | # Print deprecation notices to the Rails logger
20 | config.active_support.deprecation = :log
21 |
22 | # Only use best-standards-support built into browsers
23 | config.action_dispatch.best_standards_support = :builtin
24 |
25 | # Raise exception on mass assignment protection for Active Record models
26 | config.active_record.mass_assignment_sanitizer = :strict
27 |
28 | # Log the query plan for queries taking more than this (works
29 | # with SQLite, MySQL, and PostgreSQL)
30 | config.active_record.auto_explain_threshold_in_seconds = 0.5
31 |
32 | # Do not compress assets
33 | config.assets.compress = false
34 |
35 | # Expands the lines which load the assets
36 | config.assets.debug = true
37 | end
38 |
--------------------------------------------------------------------------------
/app/views/users/show.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, t(".title") %>
2 |
3 |
4 | <%= image_tag avatar_url(@user), :size => "48x48", :alt => @user.name, :class => "avatar" %>
5 | <%= link_to t("layouts.application.sign_out"), sign_out_url, :class => "link-with-icon" %>
6 |
7 |
10 |
11 | <%= t(".providers") %>:
12 |
13 |
14 | <% for provider in Authentication::PROVIDERS.keys - @user.providers %>
15 |
16 | <%= image_tag("#{provider}_64.png", :size => "64x64") %>
17 | <%= Authentication::PROVIDERS[provider] %>
18 | <%= link_to t(".add_provider"), "/auth/#{provider}", :class => "positive small button min-width uppercase" %>
19 |
20 | <% end %>
21 |
22 | <% for authentication in @user.authentications %>
23 |
24 | <%= image_tag("#{authentication.provider}_64.png", :size => "64x64") %>
25 | <%= authentication.provider_name %>
26 | <%= link_to(t(".remove_provider"), [current_user, authentication], :method => :delete, :class => "negative small button min-width uppercase") if can?(:destroy, authentication) %>
27 |
28 | <% end %>
29 |
30 |
--------------------------------------------------------------------------------
/spec/controllers/comments_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe CommentsController do
4 | let(:user) { mock_model(User, :admin? => false, :guest? => false) }
5 | let(:item) { mock_model(Item).as_null_object }
6 | let(:comment) { mock_model(Comment).as_null_object }
7 |
8 | before do
9 | controller.stub(:current_user).and_return(user)
10 | Item.stub(:find).and_return(item)
11 | end
12 |
13 | describe "XHR POST create" do
14 | before do
15 | item.stub_chain(:comments, :new).and_return(comment)
16 | end
17 |
18 | it "assigns @item" do
19 | xhr :post, :create, :item_id => item.id
20 | assigns[:item].should_not be_nil
21 | end
22 |
23 | it "creates a new comment" do
24 | item.comments.should_receive(:new)
25 | xhr :post, :create, :item_id => item.id
26 | end
27 |
28 | it "assigns @comment" do
29 | xhr :post, :create, :item_id => item.id
30 | assigns[:comment].should_not be_nil
31 | end
32 |
33 | it "saves the new comment" do
34 | comment.should_receive(:save)
35 | xhr :post, :create, :item_id => item.id
36 | end
37 |
38 | context "when user is a guest" do
39 | before { controller.stub(:current_user).and_return(nil) }
40 |
41 | it "sets flash notice" do
42 | xhr :post, :create, :item_id => item.id
43 | flash[:notice].should_not be_blank
44 | end
45 |
46 | it "redirects to sign in URL" do
47 | xhr :post, :create, :item_id => item.id
48 | response.should redirect_to(sign_in_url)
49 | end
50 | end
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/spec/controllers/authentications_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe AuthenticationsController do
4 | let(:auth) { mock_model(Authentication).as_null_object }
5 | let(:auth_hash) { { "provider" => "twitter", "uid" => "1234", "info" => {} } }
6 |
7 | before(:each) do
8 | request.env["omniauth.auth"] = auth_hash
9 | end
10 |
11 | context "when authentication already exists" do
12 | before do
13 | Authentication.stub(:find_by_provider_and_uid).and_return(auth)
14 | end
15 |
16 | it "authenticates user" do
17 | controller.should_receive(:current_user=)
18 | get :create, :provider => "twitter"
19 | end
20 |
21 | it "redirects to home page" do
22 | get :create, :provider => "twitter"
23 | response.should redirect_to(root_url)
24 | end
25 | end
26 |
27 | context "when authentication does not exist yet" do
28 | before do
29 | Authentication.stub(:find_by_provider_and_uid).and_return(nil)
30 | Authentication.stub(:create_with_omniauth).and_return(auth)
31 | end
32 |
33 | it "creates a new athentication" do
34 | Authentication.should_receive(:create_with_omniauth!).
35 | with(auth_hash, nil).
36 | and_return(auth)
37 | get :create, :provider => "twitter"
38 | end
39 |
40 | it "authenticates user" do
41 | controller.should_receive(:current_user=)
42 | get :create, :provider => "twitter"
43 | end
44 |
45 | it "redirects to home page" do
46 | get :create, :provider => "twitter"
47 | response.should redirect_to(root_url)
48 | end
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2016, Alexander Sulim
2 | http://rubyflow.ru/
3 | All rights reserved.
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction except as noted below, including without
8 | limitation the rights to use, copy, modify, merge, publish, distribute, and/or
9 | sublicense, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | - The Software and/or source code cannot be copied in whole and sold without
13 | meaningful modification for a profit.
14 |
15 | - The above copyright notice and this permission notice shall be included in
16 | all copies or substantial portions of the Software.
17 |
18 | - Redistributions of source code must retain the above copyright notice, this
19 | list of conditions and the following disclaimer.
20 |
21 | - Redistributions in binary form must reproduce the above copyright notice,
22 | this list of conditions and the following disclaimer in the documentation
23 | and/or other materials provided with the distribution.
24 |
25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
27 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
28 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
29 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
14 |
15 |
16 |
17 |
18 |
19 | 444444444 000000000 444444444
20 | 4::::::::4 00:::::::::00 4::::::::4
21 | 4:::::::::4 00:::::::::::::00 4:::::::::4
22 | 4::::44::::4 0:::::::000:::::::0 4::::44::::4
23 | 4::::4 4::::4 0::::::0 0::::::0 4::::4 4::::4
24 | 4::::4 4::::4 0:::::0 0:::::0 4::::4 4::::4
25 | 4::::4 4::::4 0:::::0 0:::::0 4::::4 4::::4
26 | 4::::444444::::4440:::::0 000 0:::::04::::444444::::444
27 | 4::::::::::::::::40:::::0 000 0:::::04::::::::::::::::4
28 | 4444444444:::::4440:::::0 0:::::04444444444:::::444
29 | 4::::4 0:::::0 0:::::0 4::::4
30 | 4::::4 0::::::0 0::::::0 4::::4
31 | 4::::4 0:::::::000:::::::0 4::::4
32 | 44::::::44 00:::::::::::::00 44::::::44
33 | 4::::::::4 00:::::::::00 4::::::::4
34 | 4444444444 000000000 4444444444
35 |
36 | The page you were looking for doesn't exist.
37 | You may have mistyped the address or the page may have moved.
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Rbflow::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Configure static asset server for tests with Cache-Control for performance
11 | config.serve_static_assets = true
12 | config.static_cache_control = "public, max-age=3600"
13 |
14 | # Log error messages when you accidentally call methods on nil
15 | config.whiny_nils = true
16 |
17 | # Show full error reports and disable caching
18 | config.consider_all_requests_local = true
19 | config.action_controller.perform_caching = false
20 |
21 | # Raise exceptions instead of rendering exception templates
22 | config.action_dispatch.show_exceptions = false
23 |
24 | # Disable request forgery protection in test environment
25 | config.action_controller.allow_forgery_protection = false
26 |
27 | # Tell Action Mailer not to deliver emails to the real world.
28 | # The :test delivery method accumulates sent emails in the
29 | # ActionMailer::Base.deliveries array.
30 | config.action_mailer.delivery_method = :test
31 |
32 | # Raise exception on mass assignment protection for Active Record models
33 | config.active_record.mass_assignment_sanitizer = :strict
34 |
35 | # Print deprecation notices to the stderr
36 | config.active_support.deprecation = :stderr
37 | end
38 |
--------------------------------------------------------------------------------
/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
14 |
15 |
16 |
17 |
18 |
19 | 444444444 222222222222222 222222222222222
20 | 4::::::::4 2:::::::::::::::22 2:::::::::::::::22
21 | 4:::::::::4 2::::::222222:::::2 2::::::222222:::::2
22 | 4::::44::::4 2222222 2:::::2 2222222 2:::::2
23 | 4::::4 4::::4 2:::::2 2:::::2
24 | 4::::4 4::::4 2:::::2 2:::::2
25 | 4::::4 4::::4 2222::::2 2222::::2
26 | 4::::444444::::444 22222::::::22 22222::::::22
27 | 4::::::::::::::::4 22::::::::222 22::::::::222
28 | 4444444444:::::444 2:::::22222 2:::::22222
29 | 4::::4 2:::::2 2:::::2
30 | 4::::4 2:::::2 2:::::2
31 | 4::::4 2:::::2 2222222:::::2 222222
32 | 44::::::442::::::2222222:::::22::::::2222222:::::2
33 | 4::::::::42::::::::::::::::::22::::::::::::::::::2
34 | 44444444442222222222222222222222222222222222222222
35 |
36 | The change you wanted was rejected.
37 | Maybe you tried to change something you didn't have access to.
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
14 |
15 |
16 |
17 |
18 |
19 | 555555555555555555 000000000 000000000
20 | 5::::::::::::::::5 00:::::::::00 00:::::::::00
21 | 5::::::::::::::::5 00:::::::::::::00 00:::::::::::::00
22 | 5:::::555555555555 0:::::::000:::::::00:::::::000:::::::0
23 | 5:::::5 0::::::0 0::::::00::::::0 0::::::0
24 | 5:::::5 0:::::0 0:::::00:::::0 0:::::0
25 | 5:::::5555555555 0:::::0 0:::::00:::::0 0:::::0
26 | 5:::::::::::::::5 0:::::0 000 0:::::00:::::0 000 0:::::0
27 | 555555555555:::::5 0:::::0 000 0:::::00:::::0 000 0:::::0
28 | 5:::::50:::::0 0:::::00:::::0 0:::::0
29 | 5:::::50:::::0 0:::::00:::::0 0:::::0
30 | 5555555 5:::::50::::::0 0::::::00::::::0 0::::::0
31 | 5::::::55555::::::50:::::::000:::::::00:::::::000:::::::0
32 | 55:::::::::::::55 00:::::::::::::00 00:::::::::::::00
33 | 55:::::::::55 00:::::::::00 00:::::::::00
34 | 555555555 000000000 000000000
35 |
36 | We're sorry, but something went wrong.
37 | We've been notified about this issue and we'll take a look at it shortly.
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/spec/models/item_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Item do
4 | subject { FactoryGirl.build(:item) }
5 |
6 | it "is valid with valid attributes" do
7 | subject.should be_valid
8 | end
9 |
10 | it "is not valid without user" do
11 | subject.user = nil
12 | subject.should_not be_valid
13 | end
14 |
15 | it "is not valid without title" do
16 | subject.title = nil
17 | subject.should_not be_valid
18 | end
19 |
20 | it "is not valid without markdown" do
21 | subject.markdown = nil
22 | subject.should_not be_valid
23 | end
24 |
25 | context "before save" do
26 | before(:each) { subject.save! }
27 |
28 | it "convert markdown to HTML" do
29 | subject.html.should include("")
30 | end
31 |
32 | it "assigns html" do
33 | subject.html.should_not be_blank
34 | end
35 | end
36 |
37 | describe "#author?" do
38 | context "when given user is author of item" do
39 | it "returns true" do
40 | subject.author?(subject.user).should be_true
41 | end
42 | end
43 | context "when given user is not author of item" do
44 | it "returns false" do
45 | subject.author?(FactoryGirl.create(:user)).should be_false
46 | end
47 | end
48 | end
49 |
50 | describe "#author_name" do
51 | context "when item has author" do
52 | it "returns user's name" do
53 | subject.author_name.should == subject.user.name
54 | end
55 | end
56 | context "when item does not have author" do
57 | it "returns emtry string" do
58 | subject.user = nil
59 | subject.author_name.should == ""
60 | end
61 | end
62 | end
63 | end
64 |
--------------------------------------------------------------------------------
/public/markdown-reference/README.md:
--------------------------------------------------------------------------------
1 | # Human Markdown Reference
2 |
3 | The Human Markdown Reference is a set of short, easy to understand HTML pages you can include in any project that uses Markdown.
4 |
5 | Consider this a fork of [Human Textile Reference](http://github.com/Aupajo/human-textile-reference).
6 |
7 | It is not designed to be a complete reference. Just a quick guide for the layman. For detailed detailed markdown syntax, check the [Markdown page at Daring Fireball](http://daringfireball.net/projects/markdown/).
8 |
9 | It is perfect for including as a pop-up help window next to your textarea.
10 |
11 | # Example
12 |
13 | You can see an example [here](https://webtranslateit.com/markdown-reference/).
14 |
15 | # How To Use
16 |
17 | Copy `markdown-reference` to your project.
18 |
19 | Add a help link to the reference:
20 |
21 | ## HTML Snippet
22 |
23 | You can format your text using
24 | Markdown .
25 |
26 | ## Rails Snippet
27 |
28 | You can format your text using
29 | <%= link_to 'Markdown', '/markdown-reference/index.html', :popup => ['markdown_reference', 'height=400,width=600,scrollbars=1'] %>
30 |
31 | # Internationalization
32 |
33 | You may need a different language than English. Human Markdown reference is current translated into:
34 |
35 | * Catalan
36 | * French
37 | * Russian
38 | * Spanish
39 | * Swedish
40 |
41 | If you spot a mistake or want to contribute a new language, [request an invitation](https://webtranslateit.com/projects/386-HTML-Markdown-Reference/invitation_request) to the translation project.
42 |
43 | Add a help link to the reference:
44 |
45 | ## HTML Snippet
46 |
47 | You can format your text using
48 | Markdown .
49 |
50 | where `xx` is the code of the locale you want to use.
51 |
52 | ## Rails Snippet
53 |
54 | You can format your text using
55 | <%= link_to 'Markdown', "/markdown-reference/#{I18n.locale}", :popup => ['markdown_reference', 'height=400,width=600,scrollbars=1'] %>
56 |
57 | # Contributors
58 |
59 | * Alex Soulim (Russian translations),
60 | * Pere Joan Martorell (Catalan and Spanish translations).
61 |
--------------------------------------------------------------------------------
/app/views/items/index.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, t(".title") %>
2 |
3 | <% if params[:page].blank? %>
4 |
12 | <% end %>
13 |
14 | <% if !@items.blank? %>
15 | <% @items.group_by{ |item| item.created_at.to_date }.each do |created_at, items| %>
16 |
17 |
18 | <%= created_at.strftime("%d") %> .<%= created_at.strftime("%m") %> <%= created_at.strftime("%Y") %>
19 |
20 |
21 | <% for item in items %>
22 |
23 |
24 | <%= link_to item.title, item %><%= item.author_name %>
25 |
26 |
27 |
28 |
29 |
30 |
31 | <%=raw item.html %>
32 | <% if !item.comments.blank? %>
33 |
45 | <% end %>
46 |
47 | <% end %>
48 |
49 |
50 | <% end %>
51 | <%= paginate @items %>
52 | <% end %>
53 |
--------------------------------------------------------------------------------
/public/markdown-reference/stylesheets/markdown-reference.css:
--------------------------------------------------------------------------------
1 | /* General */
2 |
3 | body, input, textarea, select {
4 | color: #222;
5 | font: 9pt "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, sans-serif;
6 | }
7 |
8 | body {
9 | background-color: #d1d7e2;
10 | line-height: 1.6em;
11 | margin: 0;
12 | }
13 |
14 | /* Formatting */
15 |
16 | p {
17 | margin-top: 0;
18 | }
19 |
20 | /* Headings */
21 |
22 | h1, h2, h3 {
23 | margin: 0;
24 | }
25 |
26 | h1 {
27 | font-size: 1.6em;
28 | }
29 |
30 | h2 {
31 | font-size: 1.4em;
32 | }
33 |
34 | h3 {
35 | font-size: 1.2em;
36 | }
37 |
38 | /* Lists */
39 |
40 | ul, ol {
41 | margin: 0;
42 | padding-left: 1.5em;
43 | }
44 |
45 | /* Links */
46 |
47 | a:link, a:visited {
48 | color: #376bd5;
49 | }
50 |
51 | a:hover {
52 | color: #ff5c07;
53 | }
54 |
55 | a:active {
56 | color: #910;
57 | }
58 |
59 | a img {
60 | border-style: none;
61 | }
62 |
63 | /* Tables */
64 |
65 | table {
66 | border-top: 1px solid #fff;
67 | border-collapse: collapse;
68 | width: 100%;
69 | }
70 |
71 | td, th {
72 | border-left: 1px solid #d9d9d9;
73 | padding: 5px 10px;
74 | width: 50%;
75 | }
76 |
77 |
78 | th {
79 | background-color: #eee;
80 | border-bottom: 1px solid #d9d9d9;
81 | text-align: left;
82 | }
83 |
84 | tr.alternate {
85 | background-color: #f1f5fa;
86 | }
87 |
88 | table table {
89 | margin: 10px 0;
90 | width: auto;
91 | }
92 |
93 | table table th, table table td {
94 | background-color: #fff;
95 | border: 1px solid #d9d9d9;
96 | padding: 0.2em 0.5em;
97 | width: auto;
98 | }
99 |
100 | /* Forms */
101 |
102 | form {
103 | border-top: 1px solid #ccc;
104 | padding: 1em;
105 | margin-top: 1em;
106 | }
107 |
108 | /* Special */
109 |
110 | #title {
111 | background-color: #a1adcb;
112 | border-bottom: 1px solid #b8bdc7;
113 | color: #444;
114 | padding: 10px 10px;
115 | text-shadow: 0px 1px 0px #cdd9fd;
116 | }
117 |
118 | .section-name {
119 | background: url('../images/arrow_down.gif') no-repeat center left;
120 | color: #525252;
121 | cursor: pointer;
122 | display: block;
123 | font-size: 1em;
124 | padding: 5px 10px 5px 16px;
125 | text-shadow: 0 1px 0 #fff;
126 | text-transform: uppercase;
127 | }
128 |
129 | .deselected {
130 | background-image: url('../images/arrow_right.gif');
131 | }
132 |
133 | .section {
134 | border-color: #b8bdc7;
135 | border-style: solid;
136 | border-width: 1px 0;
137 | background-color: white;
138 | }
--------------------------------------------------------------------------------
/app/views/items/show.html.erb:
--------------------------------------------------------------------------------
1 | <% content_for :title, @item.title %>
2 | <% content_for :meta_description, @item.title %>
3 | <% content_for :meta_author, @item.author_name %>
4 |
5 |
6 |
7 | <%= @item.created_at.strftime("%d") %> .<%= @item.created_at.strftime("%m") %> <%= @item.created_at.strftime("%Y") %>
8 |
9 |
10 |
11 |
12 |
13 | <%= @item.title %><%= @item.author_name %>
14 |
15 |
16 |
17 |
18 |
19 |
20 | <%= @item.html.html_safe %>
21 |
37 |
38 |
39 |
40 | <% if can?(:edit, @item) %>
41 |
45 | <% end %>
46 |
47 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Rbflow::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb
3 |
4 | # Code is not reloaded between requests
5 | config.cache_classes = true
6 |
7 | # Full error reports are disabled and caching is turned on
8 | config.consider_all_requests_local = false
9 | config.action_controller.perform_caching = true
10 |
11 | # Disable Rails's static asset server (Apache or nginx will already do this)
12 | config.serve_static_assets = false
13 |
14 | # Compress JavaScripts and CSS
15 | config.assets.compress = true
16 |
17 | # Don't fallback to assets pipeline if a precompiled asset is missed
18 | config.assets.compile = false
19 |
20 | # Generate digests for assets URLs
21 | config.assets.digest = true
22 |
23 | # Defaults to nil and saved in location specified by config.assets.prefix
24 | # config.assets.manifest = YOUR_PATH
25 |
26 | # Specifies the header that your server uses for sending files
27 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
28 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
29 |
30 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
31 | # config.force_ssl = true
32 |
33 | # See everything in the log (default is :info)
34 | # config.log_level = :debug
35 |
36 | # Prepend all log lines with the following tags
37 | # config.log_tags = [ :subdomain, :uuid ]
38 |
39 | # Use a different logger for distributed setups
40 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
41 |
42 | # Use a different cache store in production
43 | # config.cache_store = :mem_cache_store
44 |
45 | # Enable serving of images, stylesheets, and JavaScripts from an asset server
46 | # config.action_controller.asset_host = "http://assets.example.com"
47 |
48 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
49 | # config.assets.precompile += %w( search.js )
50 |
51 | # Disable delivery errors, bad email addresses will be ignored
52 | # config.action_mailer.raise_delivery_errors = false
53 |
54 | # Enable threaded mode
55 | # config.threadsafe!
56 |
57 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
58 | # the I18n.default_locale when a translation can not be found)
59 | config.i18n.fallbacks = true
60 |
61 | # Send deprecation notices to registered listeners
62 | config.active_support.deprecation = :notify
63 |
64 | # Log the query plan for queries taking more than this (works
65 | # with SQLite, MySQL, and PostgreSQL)
66 | # config.active_record.auto_explain_threshold_in_seconds = 0.5
67 | end
68 |
--------------------------------------------------------------------------------
/config/locales/activerecord.ru.yml:
--------------------------------------------------------------------------------
1 | ru:
2 | activerecord:
3 | errors:
4 | template:
5 | header:
6 | one: "%{model}: сохранение не удалось из-за %{count} ошибки"
7 | few: "%{model}: сохранение не удалось из-за %{count} ошибок"
8 | many: "%{model}: сохранение не удалось из-за %{count} ошибок"
9 | other: "%{model}: сохранение не удалось из-за %{count} ошибки"
10 |
11 | body: "Проблемы возникли со следующими полями:"
12 |
13 | messages:
14 | inclusion: "имеет непредусмотренное значение"
15 | exclusion: "имеет зарезервированное значение"
16 | invalid: "имеет неверное значение"
17 | confirmation: "не совпадает с подтверждением"
18 | accepted: "нужно подтвердить"
19 | empty: "не может быть пустым"
20 | blank: "не может быть пустым"
21 | too_long:
22 | one: "слишком большой длины (не может быть больше чем %{count} символ)"
23 | few: "слишком большой длины (не может быть больше чем %{count} символа)"
24 | many: "слишком большой длины (не может быть больше чем %{count} символов)"
25 | other: "слишком большой длины (не может быть больше чем %{count} символа)"
26 | too_short:
27 | one: "недостаточной длины (не может быть меньше %{count} символа)"
28 | few: "недостаточной длины (не может быть меньше %{count} символов)"
29 | many: "недостаточной длины (не может быть меньше %{count} символов)"
30 | other: "недостаточной длины (не может быть меньше %{count} символа)"
31 | wrong_length:
32 | one: "неверной длины (может быть длиной ровно %{count} символ)"
33 | few: "неверной длины (может быть длиной ровно %{count} символа)"
34 | many: "неверной длины (может быть длиной ровно %{count} символов)"
35 | other: "неверной длины (может быть длиной ровно %{count} символа)"
36 | taken: "уже существует"
37 | not_a_number: "не является числом"
38 | greater_than: "может иметь значение большее %{count}"
39 | greater_than_or_equal_to: "может иметь значение большее или равное %{count}"
40 | equal_to: "может иметь лишь значение, равное %{count}"
41 | less_than: "может иметь значение меньшее чем %{count}"
42 | less_than_or_equal_to: "может иметь значение меньшее или равное %{count}"
43 | odd: "может иметь лишь четное значение"
44 | even: "может иметь лишь нечетное значение"
45 | record_invalid: "Возникли ошибки: %{errors}"
46 |
47 | full_messages:
48 | format: "%{attribute} %{message}"
49 |
50 | attributes:
51 | user:
52 | name: "Имя"
53 | email: "Электронная почта"
54 | item:
55 | title: "Заголовок"
56 | markdown: "Текст статьи"
57 | comment:
58 | markdown: "Текст комментария"
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/code.css:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | github.com style (c) Vasily Polovnyov
4 |
5 | */
6 | pre {
7 | padding:0.5em 1em;
8 | -webkit-border-radius:5px;
9 | -moz-border-radius:5px;
10 | border-radius:5px;
11 | border:#CCC 1px dashed;
12 | background-color:#f8f8ff;
13 | -word-wrap:break-word;
14 | overflow:auto;
15 | font-family:Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;
16 | }
17 | code {}
18 | pre,
19 | code {
20 | font-family:Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;
21 | font-size:12px;
22 | }
23 | pre code {
24 | -display: block;
25 | -padding: 0.5em;
26 | -color: #000;
27 | }
28 |
29 | pre .comment,
30 | pre .template_comment,
31 | pre .diff .header,
32 | pre .javadoc {
33 | color: #998;
34 | font-style: italic
35 | }
36 |
37 | pre .keyword,
38 | pre .css .rule .keyword,
39 | pre .winutils,
40 | pre .javascript .title,
41 | pre .lisp .title,
42 | pre .subst {
43 | color: #000;
44 | font-weight: bold
45 | }
46 |
47 | pre .number,
48 | pre .hexcolor {
49 | color: #40a070
50 | }
51 |
52 | pre .string,
53 | pre .tag .value,
54 | pre .phpdoc,
55 | pre .tex .formula {
56 | color: #d14
57 | }
58 |
59 | pre .title,
60 | pre .id {
61 | color: #900;
62 | font-weight: bold
63 | }
64 |
65 | pre .javascript .title,
66 | pre .lisp .title,
67 | pre .subst {
68 | font-weight: normal
69 | }
70 |
71 | pre .class .title,
72 | pre .tex .command {
73 | color: #458;
74 | font-weight: bold
75 | }
76 |
77 | pre .tag,
78 | pre .css .keyword,
79 | pre .html .keyword,
80 | pre .tag .title,
81 | pre .django .tag .keyword {
82 | color: #000080;
83 | font-weight: normal
84 | }
85 |
86 | pre .attribute,
87 | pre .variable,
88 | pre .instancevar,
89 | pre .lisp .body {
90 | color: #008080
91 | }
92 |
93 | pre .regexp {
94 | color: #009926
95 | }
96 |
97 | pre .class {
98 | color: #458;
99 | font-weight: bold
100 | }
101 |
102 | pre .symbol,
103 | pre .ruby .symbol .string,
104 | pre .ruby .symbol .keyword,
105 | pre .ruby .symbol .keymethods,
106 | pre .lisp .keyword,
107 | pre .tex .special {
108 | color: #990073
109 | }
110 |
111 | pre .builtin,
112 | pre .built_in,
113 | pre .lisp .title {
114 | color: #0086b3
115 | }
116 |
117 | pre .preprocessor,
118 | pre .pi,
119 | pre .doctype,
120 | pre .shebang,
121 | pre .cdata {
122 | color: #999;
123 | font-weight: bold
124 | }
125 |
126 | pre .deletion {
127 | background: #fdd
128 | }
129 |
130 | pre .addition {
131 | background: #dfd
132 | }
133 |
134 | pre .diff .change {
135 | background: #0086b3
136 | }
137 |
138 | pre .chunk {
139 | color: #aaa
140 | }
141 |
142 | pre .tex .formula {
143 | opacity: 0.5;
144 | }
145 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | if defined?(Bundler)
6 | # If you precompile assets before deploying to production, use this line
7 | Bundler.require(*Rails.groups(:assets => %w(development test)))
8 | # If you want your assets lazily compiled in production, use this line
9 | # Bundler.require(:default, :assets, Rails.env)
10 | end
11 |
12 | module Rbflow
13 | class Application < Rails::Application
14 | # Settings in config/environments/* take precedence over those specified here.
15 | # Application configuration should go into files in config/initializers
16 | # -- all .rb files in that directory are automatically loaded.
17 |
18 | # Custom directories with classes and modules you want to be autoloadable.
19 | # config.autoload_paths += %W(#{config.root}/extras)
20 |
21 | # Only load the plugins named here, in the order given (default is alphabetical).
22 | # :all can be used as a placeholder for all plugins not explicitly named.
23 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
24 |
25 | # Activate observers that should always be running.
26 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
27 |
28 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
29 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
30 | # config.time_zone = 'Central Time (US & Canada)'
31 |
32 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
33 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
34 | config.i18n.default_locale = :ru
35 |
36 | # Configure the default encoding used in templates for Ruby 1.9.
37 | config.encoding = "utf-8"
38 |
39 | # Configure sensitive parameters which will be filtered from the log file.
40 | config.filter_parameters += [:password]
41 |
42 | # Enable escaping HTML in JSON.
43 | config.active_support.escape_html_entities_in_json = true
44 |
45 | # Use SQL instead of Active Record's schema dumper when creating the database.
46 | # This is necessary if your schema can't be completely dumped by the schema dumper,
47 | # like if you have constraints or database-specific column types
48 | # config.active_record.schema_format = :sql
49 |
50 | # Enforce whitelist mode for mass assignment.
51 | # This will create an empty whitelist of attributes available for mass-assignment for all models
52 | # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
53 | # parameters by using an attr_accessible or attr_protected declaration.
54 | config.active_record.whitelist_attributes = true
55 |
56 | # Enable the asset pipeline
57 | config.assets.enabled = true
58 |
59 | # Version of your assets, change this if you want to expire all your assets
60 | config.assets.version = '1.0'
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/spec/models/user_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe User do
4 | subject { FactoryGirl.build(:user) }
5 |
6 | describe ".create_with_omniauth!" do
7 | let(:auth) do
8 | {
9 | "info" => {
10 | "name" => "John Doe",
11 | "email" => "john.doe@example.com",
12 | "image" => "http://example.com/images/avatar.png"
13 | }
14 | }
15 | end
16 | subject { User.create_with_omniauth!(auth) }
17 |
18 | it "creates a new user with given name" do
19 | subject.name.should == auth["info"]["name"]
20 | end
21 |
22 | it "creates a new user with given email" do
23 | subject.email.should == auth["info"]["email"]
24 | end
25 |
26 | it "creates a new user with given avatar's URL" do
27 | subject.avatar_url.should == auth["info"]["image"]
28 | end
29 | end
30 |
31 | User::ROLES.each_key do |role|
32 | describe "##{role}?" do
33 | context "when a user has role '#{role}'" do
34 | before(:each) { subject.role = User::ROLES[role] }
35 |
36 | it "returns true" do
37 | subject.send("#{role}?").should be_true
38 | end
39 | end
40 | context "when a user does not have role 'admin'" do
41 | before(:each) { subject.role = nil }
42 |
43 | it "returns false" do
44 | subject.send("#{role}?").should be_false
45 | end
46 | end
47 | end
48 | end
49 |
50 | describe "#approved?" do
51 | context "when user is approved" do
52 | before(:each) { subject.update_attributes!(:approved_at => Time.now) }
53 |
54 | it "returns true" do
55 | subject.approved?.should be_true
56 | end
57 | end
58 | context "when user is not approved" do
59 | it "returns false" do
60 | subject.approved?.should be_false
61 | end
62 | end
63 | end
64 |
65 | describe "#approve!" do
66 | it "sets approved status" do
67 | subject.approve!
68 | subject.should be_approved
69 | end
70 | end
71 |
72 | describe "#unapprove!" do
73 | before(:each) { subject.update_attributes!(:approved_at => Time.now) }
74 |
75 | it "drops approved status" do
76 | subject.unapprove!
77 | subject.should_not be_approved
78 | end
79 | end
80 |
81 | describe "#guest?" do
82 | context "when a user has not been saved" do
83 | it "returns true" do
84 | subject.guest?.should be_true
85 | end
86 | end
87 | context "when a user has been saved" do
88 | before(:each) { subject.save! }
89 |
90 | it "returns false" do
91 | subject.guest?.should be_false
92 | end
93 | end
94 | end
95 |
96 | describe "#me?" do
97 | before(:each) { subject.save! }
98 |
99 | context "when given user is the same person" do
100 | it "returns true" do
101 | subject.me?(subject).should be_true
102 | end
103 | end
104 | context "when given user is not the same person" do
105 | it "returns false" do
106 | subject.me?(FactoryGirl.create(:user)).should be_false
107 | end
108 | end
109 | end
110 | end
111 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/wmd.css:
--------------------------------------------------------------------------------
1 | .wmd-panel {
2 | margin-left: 25%;
3 | margin-right: 25%;
4 | width: 50%;
5 | min-width: 500px;
6 | }
7 |
8 | #wmd-editor {
9 | background-color: Aquamarine;
10 | }
11 |
12 | .wmd-button-bar {
13 | width:100%;
14 | margin:0;
15 | padding:0;
16 | }
17 |
18 | .wmd-input {
19 | height: 500px;
20 | width: 100%;
21 | background-color: Gainsboro;
22 | border: 1px solid DarkGray;
23 | }
24 |
25 | .wmd-preview {
26 | min-height:380px;
27 | padding:6px 8px;
28 | -webkit-border-radius:4px;
29 | -moz-border-radius:4px;
30 | border-radius:4px;
31 | border:rgba(207, 60, 37, 0.6) 1px dashed;
32 | }
33 | .comments .wmd-preview {
34 | min-height:1em;
35 | }
36 |
37 | .wmd-output {
38 | background-color: Pink;
39 | }
40 |
41 | .wmd-button-row {
42 | position: relative;
43 | margin-left: 5px;
44 | margin-right: 5px;
45 | margin-bottom: 5px;
46 | margin-top: 10px;
47 | padding: 0px;
48 | height: 20px;
49 | }
50 |
51 | .wmd-spacer {
52 | width: 1px;
53 | height: 20px;
54 | margin-left: 7px;
55 | margin-right:7px;
56 |
57 | position: relative;
58 | background-color: Silver;
59 | display: inline-block;
60 | list-style: none;
61 | }
62 |
63 | .wmd-button {
64 | width: 20px;
65 | height: 20px;
66 | margin-left: 5px;
67 | margin-right: 5px;
68 |
69 | position: relative;
70 | background-image: url(/assets/wmd-buttons.png);
71 | background-repeat: no-repeat;
72 | background-position: 0px 0px;
73 | display: inline-block;
74 | list-style: none;
75 | cursor:pointer;
76 | }
77 |
78 | .wmd-button > a {
79 | width: 20px;
80 | height: 20px;
81 | margin-left: 5px;
82 | margin-right: 5px;
83 |
84 | position: absolute;
85 | display: inline-block;
86 | }
87 |
88 |
89 | /* sprite button slicing style information */
90 | .wmd-bold-button {background-position: 0px 0;}
91 | .wmd-italic-button {background-position: -20px 0;}
92 | .wmd-spacer1 {}
93 | .wmd-link-button {background-position: -40px 0;}
94 | .wmd-quote-button {background-position: -60px 0;}
95 | .wmd-code-button {background-position: -80px 0;}
96 | .wmd-image-button {background-position: -100px 0;}
97 | .wmd-spacer2 {}
98 | .wmd-olist-button {background-position: -120px 0;}
99 | .wmd-ulist-button {background-position: -140px 0;}
100 | .wmd-heading-button {background-position: -160px 0;}
101 | .wmd-hr-button {background-position: -180px 0;}
102 | .wmd-spacer3 {}
103 | .wmd-undo-button {background-position: -200px 0;}
104 | .wmd-redo-button {background-position: -220px 0;}
105 | .wmd-help-button {position:absolute;right: 0px; background-position: -240px 0;}
106 |
107 |
108 | .wmd-prompt-background {
109 | background-color:#000;
110 | }
111 |
112 | .wmd-prompt-dialog {
113 | padding:0.5em 1em;
114 | -webkit-border-radius:5px;
115 | -moz-border-radius:5px;
116 | border-radius:5px;
117 | -border:1px solid #999999;
118 | background-color:#F5F5F5;
119 | }
120 |
121 | .wmd-prompt-dialog > div {
122 | -font-size: 0.8em;
123 | -font-family: arial, helvetica, sans-serif;
124 | }
125 |
126 |
127 | .wmd-prompt-dialog > form > input[type="text"] {
128 | -border: 1px solid #999999;
129 | -color: black;
130 | }
131 |
132 | .wmd-prompt-dialog > form > input[type="button"] {
133 | -border: 1px solid #888888;
134 | -font-family: trebuchet MS, helvetica, sans-serif;
135 | -font-size: 0.8em;
136 | -font-weight: bold;
137 | }
138 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/form.css:
--------------------------------------------------------------------------------
1 | /* ------------------------------------------------------------------------
2 | = Forms
3 | ------------------------------------------------------------------------ */
4 | .form {
5 | position:relative;
6 | margin:0;
7 | padding:0;
8 | }
9 | .form label {
10 | display:inline-block;
11 | width:100px;
12 | font-weight:bold;
13 | }
14 | .form div {
15 | margin-bottom:1em;
16 | }
17 | .form div.indented {
18 | padding-left:104px;
19 | }
20 | .form .field_with_errors {
21 | display:inline;
22 | }
23 | .form .field_with_errors label {
24 | color:#B00;
25 | }
26 | .form .field_with_errors input,
27 | .form .field_with_errors textarea {
28 | border:#B00 1px solid;
29 | }
30 | .form .buttons {
31 |
32 | }
33 | .form .buttons a {
34 | font-size:12px;
35 | }
36 |
37 | input[type="password"], input[type="text"], textarea {
38 | margin:0;
39 | padding:6px 8px 6px;
40 | -webkit-border-radius:4px;
41 | -moz-border-radius:4px;
42 | border-radius:4px;
43 | border:1px solid #999;
44 | font-size:12px;
45 | color:inherit;
46 | }
47 |
48 | /* Buttons */
49 | input[type="button"]::-moz-focus-inner,
50 | input[type="submit"]::-moz-focus-inner,
51 | input[type="reset"]::-moz-focus-inner,
52 | input[type="image"]::-moz-focus-inner,
53 | button::-moz-focus-inner,
54 | .button::-moz-focus-inner,
55 | .button.small::-moz-focus-inner {
56 | border:0;
57 | }
58 | input[type="button"],
59 | input[type="submit"],
60 | input[type="reset"],
61 | input[type="image"],
62 | button,
63 | .button,
64 | .button.small {
65 | display:inline-block;
66 | color:inherit;
67 | border:1px solid #999;
68 | margin:0;
69 | overflow:visible;
70 | background:-webkit-gradient(linear, left top, left bottom, from(#fff), to(#e9e9e9));
71 | background:-moz-linear-gradient(top, #fff, #e9e9e9);
72 | text-decoration:none;
73 | }
74 | input[type="button"],
75 | input[type="submit"],
76 | input[type="reset"],
77 | input[type="image"],
78 | button,
79 | .button {
80 | padding:6px 8px 6px;
81 | font-size:12px;
82 | font-weight:bold;
83 | -webkit-border-radius:4px;
84 | -moz-border-radius:4px;
85 | border-radius:4px;
86 | }
87 | .button.small {
88 | padding:2px 4px;
89 | font-size:11px;
90 | font-weight:normal;
91 | -webkit-border-radius:3px;
92 | -moz-border-radius:3px;
93 | border-radius:3px;
94 | }
95 | input[type="button"]:disabled,
96 | input[type="submit"]:disabled,
97 | input[type="reset"]:disabled,
98 | input[type="image"]:disabled,
99 | button:disabled,
100 | .button:disabled,
101 | .button.small:disabled {
102 | opacity:.5;
103 | cursor:default !important;
104 | }
105 | input[type="button"]:hover,
106 | input[type="submit"]:hover,
107 | input[type="reset"]:hover,
108 | input[type="image"]:hover,
109 | button:hover,
110 | .button:hover,
111 | .button.small:hover {
112 | cursor:pointer;
113 | border:1px solid #555;
114 | }
115 | a.button:hover {
116 | background-color:transparent;
117 | color:inherit;
118 | }
119 | input[type="button"]:active,
120 | input[type="button"].active,
121 | input[type="submit"]:active,
122 | input[type="reset"]:active,
123 | input[type="image"]:active,
124 | button:active,
125 | .button:active,
126 | .button.active,
127 | .button.small:active {
128 | background:-webkit-gradient(linear, left top, left bottom, from(#AAA), to(#FFF));
129 | background:-moz-linear-gradient(top, #AAA, #FFF);
130 | border:1px solid #555;
131 | }
132 | .button.min-width {
133 | min-width:65px;
134 | padding:0;
135 | text-align:center;
136 | font-size:9px;
137 | }
138 | .button.positive {
139 | background: #00AE3E;
140 | border-color: #393 #393 #277827;
141 | color:#FFF;
142 | }
143 | .button.negative {
144 | background:#C63738;
145 | border-color: #A33 #A33 #962C2C;
146 | color:#FFF;
147 | }
148 | /* ------------------------------------------------------------------------
149 | = Item
150 | ------------------------------------------------------------------------ */
151 | .new_item input[type="text"],
152 | .new_item textarea,
153 | .edit_item input[type="text"],
154 | .edit_item textarea,
155 | .new_comment textarea,
156 | .edit_comment textarea {
157 | width:95%;
158 | }
159 | .new_item div,
160 | .edit_item div {
161 | margin-bottom:3px;
162 | }
--------------------------------------------------------------------------------
/public/markdown-reference/sv/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Markdown Handbok
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Markdown Handbok
13 |
14 | Text
15 |
16 |
17 |
18 |
19 | Markdown
20 | Resultat
21 |
22 |
23 | Texten är **fet**.
24 | Texten är fet .
25 |
26 |
27 | Texten är *kursiv*.
28 | Texten är kursiv .
29 |
30 |
31 | `Detta är lite kod.`
32 | Detta är lite kod.
33 |
34 |
35 |
36 |
37 | Rubriker
38 |
39 |
40 |
41 |
42 | Markdown
43 | Resultat
44 |
45 |
46 | # Första Rubrik
47 | Första Rubriken
48 |
49 |
50 | ## Andra Rubriken
51 | Andra Rubriken
52 |
53 |
54 | ### Tredje Rubriken
55 | Tredje Rubriken
56 |
57 |
58 |
59 |
60 | Citat
61 |
62 |
63 |
64 |
65 | > Detta är den första nivån citera.
66 | >> Detta är kapslade blockquote.
67 | > Tillbaka till första nivån.
68 |
69 |
70 | Detta är den första nivån citera.
71 | Detta är kapslade blockquote.
72 | Tillbaka till första nivån.
73 |
74 |
75 |
76 |
77 |
78 |
79 | Länkar och Bilder
80 |
81 |
82 |
83 |
84 | Länk till [Google](http://google.se).
85 | Länk till Google .
86 |
87 |
88 | Skicka mig ett e-post till <adressen@exempel.se>.
89 | Skicka mig ett e-post till adressen@exempel.se .
90 |
91 |
92 | 
93 |
94 |
95 |
96 |
97 |
98 | Listor
99 |
100 |
101 |
102 |
103 | Markdown
104 | Resultat
105 |
106 |
107 | * Mjölk
108 | * Bröd
109 | * Ost
110 | * Cheddar
111 | * Camembert
112 | * Ris
113 |
114 |
115 | Mjölk
116 | Bröd
117 | Ost
118 |
119 | Cheddar
120 | Camembert
121 |
122 |
123 | Ris
124 |
125 |
126 |
127 |
128 | 1. Mjölk
129 | 2. Bröd
130 | 3. Ost
131 | 1. Cheddar
132 | 2. Camembert
133 | 4. Ris
134 |
135 |
136 |
137 | Mjölk
138 | Bröd
139 | Ost
140 |
141 | Cheddar
142 | Camembert
143 |
144 |
145 | Ris
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/public/markdown-reference/ru/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Справочник по Markdown
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Справочник по Markdown
13 |
14 | Текст
15 |
16 |
17 |
18 |
19 | Markdown
20 | Результат
21 |
22 |
23 | Это **жирный** текст.
24 | Это bold текст.
25 |
26 |
27 | Это *курсив*.
28 | Это курсив .
29 |
30 |
31 | `Это код.`
32 | Это код.
33 |
34 |
35 |
36 |
37 | Заголовки
38 |
39 |
40 |
41 |
42 | Markdown
43 | Результат
44 |
45 |
46 | # Заголовок первого уровня
47 | Заголовок первого уровня
48 |
49 |
50 | ## Заголовок второго уровня
51 | Заголовок второго уровня
52 |
53 |
54 | ### Заголовок третьего уровня
55 | Заголовок третьего уровня
56 |
57 |
58 |
59 |
60 | Цитаты
61 |
62 |
63 |
64 |
65 | > Это первый уровень цитирования.
66 | >> Второй уровень цитирования.
67 | > И снова, первый уровень.
68 |
69 |
70 | Это первый уровень цитирования.
71 | Второй уровень цитирования.
72 | И снова, первый уровень.
73 |
74 |
75 |
76 |
77 |
78 |
79 | Ссылки и изображения
80 |
81 |
82 |
83 |
84 | Ссылка на [Google](http://google.com).
85 | Ссылка на Google .
86 |
87 |
88 | Отправьте мне электронное письмо на <address@example.com>.
89 | Отправьте мне электронное письмо на address@example.com
90 |
91 |
92 | 
93 |
94 |
95 |
96 |
97 |
98 | Списки
99 |
100 |
101 |
102 |
103 | Markdown
104 | Результат
105 |
106 |
107 | * Молоко
108 | * Хлеб
109 | * Сыр
110 | * Чеддер
111 | * Камамбер
112 | * Рис
113 |
114 |
115 | Молоко
116 | Хлеб
117 | Сыр
118 |
119 | Чеддер
120 | Камамбер
121 |
122 |
123 | Рис
124 |
125 |
126 |
127 |
128 | 1. Молоко
129 | 2. Хлеб
130 | 3. Сыр
131 | 1. Чеддер
132 | 2. Камамбер
133 | 4. Рис
134 |
135 |
136 |
137 | Молоко
138 | Хлеб
139 | Сыр
140 |
141 | Чеддер
142 | Камамбер
143 |
144 |
145 | Рис
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/public/markdown-reference/fr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Guide de référence pour Markdown
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Guide de référence pour Markdown
13 |
14 | Texte
15 |
16 |
17 |
18 |
19 | Markdown
20 | Résultat
21 |
22 |
23 | Ce texte est en **gras**.
24 | Ce texte est en gras .
25 |
26 |
27 | Ce texte est en *italique*.
28 | Ce texte est en italique. .
29 |
30 |
31 | `Ceci est du code.`
32 | Ceci est du code.
33 |
34 |
35 |
36 |
37 | Têtes de chapitre
38 |
39 |
40 |
41 |
42 | Markdown
43 | Résultat
44 |
45 |
46 | # Première tête de chapitre
47 | Première tête de chapitre
48 |
49 |
50 | ## Seconde tête de chapitre
51 | Seconde tête de chapitre
52 |
53 |
54 | ### Troisième tête de chapitre
55 | Troisième tête de chapitre
56 |
57 |
58 |
59 |
60 | Citations
61 |
62 |
63 |
64 |
65 |
66 | > Ceci est le premier niveau de citation.
67 | >> Ceci est une citation imbriquée.
68 | > Retour au premier niveau.
69 |
70 |
71 |
72 | Ceci est le premier niveau de citation.
73 | Ceci est une citation imbriquée.
74 | Retour au premier niveau.
75 |
76 |
77 |
78 |
79 |
80 |
81 | Liens et images
82 |
83 |
84 |
85 |
86 | Lien vers [Google](http://google.fr).
87 | Lien vers Google .
88 |
89 |
90 | Envoyez-mopi un e-mail à <adresse@exemple.com>.
91 | Envoyez-moi un e-mail à adresse@exemple.com .
92 |
93 |
94 | 
95 |
96 |
97 |
98 |
99 |
100 | Listes
101 |
102 |
103 |
104 |
105 | Markdown
106 | Résultat
107 |
108 |
109 | * Lait
110 | * Pain
111 | * Fromage
112 | * Gruyère
113 | * Camembert
114 | * Riz
115 |
116 |
117 | Lait
118 | Pain
119 | Fromage
120 |
121 | Gruyère
122 | Camembert
123 |
124 |
125 | Riz
126 |
127 |
128 |
129 |
130 | 1. Lait
131 | 2. Pain
132 | 3. Fromage
133 | 1. Gruyère
134 | 2. Camembert
135 | 4. Riz
136 |
137 |
138 | Lait
139 | Pain
140 | Fromage
141 |
142 | Gruyère
143 | Camembert
144 |
145 |
146 | Riz
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/public/markdown-reference/en/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Markdown Guide
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Markdown Guide
13 |
14 | Text
15 |
16 |
17 |
18 |
19 | Markdown
20 | Result
21 |
22 |
23 | This text is **bold**.
24 | This text is bold .
25 |
26 |
27 | This text is *italicized*.
28 | This text is italicized .
29 |
30 |
31 | `This is some code.`
32 | This is some code.
33 |
34 |
35 |
36 |
37 | Headings
38 |
39 |
40 |
41 |
42 | Markdown
43 | Result
44 |
45 |
46 | # First Header
47 | First Header
48 |
49 |
50 | ## Second Header
51 | Second Header
52 |
53 |
54 | ### Third Header
55 | Third Header
56 |
57 |
58 |
59 |
60 | Quotes
61 |
62 |
63 |
64 |
65 |
66 | > This is the first level of quoting.
67 | >> This is nested blockquote.
68 | > Back to the first level.
69 |
70 |
71 |
72 | This is the first level of quoting.
73 |
74 | This is nested blockquote.
75 |
76 | Back to the first level.
77 |
78 |
79 |
80 |
81 |
82 |
83 | Links and Images
84 |
85 |
86 |
87 |
88 | Link to [Google](http://google.com).
89 | Link to Google .
90 |
91 |
92 | Send me an email at .
93 | Send me an email at address@example.com .
94 |
95 |
96 | 
97 |
98 |
99 |
100 |
101 |
102 | Lists
103 |
104 |
105 |
106 |
107 | Markdown
108 | Result
109 |
110 |
111 |
112 | * Milk
113 | * Bread
114 | * Cheese
115 | * Cheddar
116 | * Camembert
117 | * Rice
118 |
119 |
120 |
121 | Milk
122 | Bread
123 | Cheese
124 |
125 | Cheddar
126 | Camembert
127 |
128 |
129 | Rice
130 |
131 |
132 |
133 |
134 |
135 | 1. Milk
136 | 2. Bread
137 | 3. Cheese
138 | 1. Cheddar
139 | 2. Camembert
140 | 4. Rice
141 |
142 |
143 |
144 | Milk
145 | Bread
146 | Cheese
147 |
148 | Cheddar
149 | Camembert
150 |
151 |
152 | Rice
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/public/markdown-reference/ca/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Guia de referència de Markdown
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Guia de referència de Markdown
13 |
14 | Text
15 |
16 |
17 |
18 |
19 | Markdown
20 | Resultat
21 |
22 |
23 | Aquest text està en **negreta**.
24 | Aquest text està en negreta .
25 |
26 |
27 | Aquest text està en *cursiva*.
28 | Aquest text està en cursiva .
29 |
30 |
31 | `Això és un tros de codi.`
32 | Això és un tros de codi.
33 |
34 |
35 |
36 |
37 | Capçaleres
38 |
39 |
40 |
41 |
42 | Markdown
43 | Resultat
44 |
45 |
46 | # Primera capçalera
47 | Primera capçalera
48 |
49 |
50 | ## Segona capçalera
51 | Segona capçalera
52 |
53 |
54 | ### Tercera capçalera
55 | Tercera capçalera
56 |
57 |
58 |
59 |
60 | Citacions
61 |
62 |
63 |
64 |
65 |
66 | > Aquest és el primer nivell de citació.
67 | >> Això és una citació sagnada.
68 | > Retorn al primer nivell.
69 |
70 |
71 |
72 | Aquest és el primer nivell de citació.
73 | Això és una citació sagnada.
74 | Retorn al primer nivell.
75 |
76 |
77 |
78 |
79 |
80 |
81 | Enllaços i imatges
82 |
83 |
84 |
85 |
86 | Enllaç a [Google](http://google.com).
87 | Enllaç a Google .
88 |
89 |
90 | Envia'm un correu a <adreça@exemple.com>.
91 | Envia'm un correu a adreça@exemple.com .
92 |
93 |
94 | 
95 |
96 |
97 |
98 |
99 |
100 | Llistes
101 |
102 |
103 |
104 |
105 | Markdown
106 | Resultat
107 |
108 |
109 | * Llet
110 | * Pa
111 | * Formatge
112 | * Gruyère
113 | * Camembert
114 | * Arròs
115 |
116 |
117 | Llet
118 | Pa
119 | Formatge
120 |
121 | Gruyère
122 | Camembert
123 |
124 |
125 | Arròs
126 |
127 |
128 |
129 |
130 |
131 | 1. Llet
132 | 2. Pa
133 | 3. Formatge
134 | 1. Gruyère
135 | 2. Camembert
136 | 4. Arròs
137 |
138 |
139 |
140 | Llet
141 | Pa
142 | Formatge
143 |
144 | Gruyère
145 | Camembert
146 |
147 |
148 | Arròs
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
--------------------------------------------------------------------------------
/public/markdown-reference/tr/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Markdown Rehberi
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Markdown Rehberi
13 |
14 | Metin
15 |
16 |
17 |
18 |
19 | Markdown
20 | Sonuç
21 |
22 |
23 | Bu metin **kalın**dır.
24 | Bu metin kalın dır.
25 |
26 |
27 | Bu metin *eğik*tir.
28 | Bu metin eğik tir.
29 |
30 |
31 | `Bu bir örnek koddur.`
32 | Bu bir örnek koddur.
33 |
34 |
35 |
36 |
37 | Başlıklar
38 |
39 |
40 |
41 |
42 | Markdown
43 | Sonuç
44 |
45 |
46 | # İlk Başlık
47 | İlk Başlık
48 |
49 |
50 | ## İkinci Başlık
51 | İkinci Başlık
52 |
53 |
54 | ### Üçüncü Başlık
55 | Üçüncü Başlık
56 |
57 |
58 |
59 |
60 | Alıntılar
61 |
62 |
63 |
64 |
65 |
66 | > Bu ilk seviye bir alıntıdır.
67 | >> Bu içiçe bir alıntıdır.
68 | > İlk seviye'ye geri dönüyoruz.
69 |
70 |
71 |
72 | Bu ilk seviye bir alıntıdır.
73 |
74 | Bu içiçe bir alıntıdır.
75 |
76 | İlk seviye'ye geri dönüyoruz.
77 |
78 |
79 |
80 |
81 |
82 |
83 | Bağlantı ve İmajlar
84 |
85 |
86 |
87 |
88 | [Google](http://google.com) bağlantısı.
89 | Google bağlantısı.
90 |
91 |
92 | bana bir email gönder.
93 | address@example.com bana bir email gönder.
94 |
95 |
96 | 
97 |
98 |
99 |
100 |
101 |
102 | Listeler
103 |
104 |
105 |
106 |
107 | Markdown
108 | Sonuç
109 |
110 |
111 |
112 | * Süt
113 | * Ekmek
114 | * Peynir
115 | * Çedar
116 | * Krema Peynir
117 | * Pirinç
118 |
119 |
120 |
121 | Süt
122 | Ekmek
123 | Peynir
124 |
125 | Çedar
126 | Krema Peynir
127 |
128 |
129 | Pirinç
130 |
131 |
132 |
133 |
134 |
135 | 1. Süt
136 | 2. Ekmek
137 | 3. Peynir
138 | 1. Çedar
139 | 2. Krema Peynir
140 | 4. Pirinç
141 |
142 |
143 |
144 | Süt
145 | Ekmek
146 | Peynir
147 |
148 | Çedar
149 | Krema Peynir
150 |
151 |
152 | Pirinç
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/public/markdown-reference/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Markdown Guide
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Markdown Guide
13 |
14 | Text
15 |
16 |
17 |
18 |
19 | Markdown
20 | Result
21 |
22 |
23 | This text is **bold**.
24 | This text is bold .
25 |
26 |
27 | This text is *italicized*.
28 | This text is italicized .
29 |
30 |
31 | `This is some code.`
32 | This is some code.
33 |
34 |
35 |
36 |
37 | Headings
38 |
39 |
40 |
41 |
42 | Markdown
43 | Result
44 |
45 |
46 | # First Header
47 | First Header
48 |
49 |
50 | ## Second Header
51 | Second Header
52 |
53 |
54 | ### Third Header
55 | Third Header
56 |
57 |
58 |
59 |
60 | Quotes
61 |
62 |
63 |
64 |
65 |
66 | > This is the first level of quoting.
67 | >> This is nested blockquote.
68 | > Back to the first level.
69 |
70 |
71 |
72 | This is the first level of quoting.
73 |
74 | This is nested blockquote.
75 |
76 | Back to the first level.
77 |
78 |
79 |
80 |
81 |
82 |
83 | Links and Images
84 |
85 |
86 |
87 |
88 | Link to [Google](http://google.com).
89 | Link to Google .
90 |
91 |
92 | Send me an email at <address@example.com>.
93 | Send me an email at address@example.com .
94 |
95 |
96 | 
97 |
98 |
99 |
100 |
101 |
102 | Lists
103 |
104 |
105 |
106 |
107 | Markdown
108 | Result
109 |
110 |
111 |
112 | * Milk
113 | * Bread
114 | * Cheese
115 | * Cheddar
116 | * Camembert
117 | * Rice
118 |
119 |
120 |
121 | Milk
122 | Bread
123 | Cheese
124 |
125 | Cheddar
126 | Camembert
127 |
128 |
129 | Rice
130 |
131 |
132 |
133 |
134 |
135 | 1. Milk
136 | 2. Bread
137 | 3. Cheese
138 | 1. Cheddar
139 | 2. Camembert
140 | 4. Rice
141 |
142 |
143 |
144 | Milk
145 | Bread
146 | Cheese
147 |
148 | Cheddar
149 | Camembert
150 |
151 |
152 | Rice
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
--------------------------------------------------------------------------------
/spec/controllers/users_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe UsersController do
4 | let(:user) { mock_model(User, :admin? => true, :guest? => false) }
5 |
6 | before { controller.stub(:current_user).and_return(user) }
7 |
8 | describe "GET index" do
9 | it "assigns @users" do
10 | User.stub_chain(:order, :page, :per).and_return([user])
11 | get :index
12 | assigns[:users].should eq([user])
13 | end
14 |
15 | context "when user is not an admin" do
16 | before { user.stub(:admin?).and_return(false) }
17 |
18 | it "sets flash notice" do
19 | get :index
20 | flash[:notice].should_not be_blank
21 | end
22 |
23 | it "redirects to sign in URL" do
24 | get :index
25 | response.should redirect_to(sign_in_url)
26 | end
27 | end
28 |
29 | context "when user is a guest" do
30 | before { controller.stub(:current_user).and_return(nil) }
31 |
32 | it "sets flash notice" do
33 | get :index
34 | flash[:notice].should_not be_blank
35 | end
36 |
37 | it "redirects to sign in URL" do
38 | get :index
39 | response.should redirect_to(sign_in_url)
40 | end
41 | end
42 | end
43 |
44 | describe "GET show" do
45 | it "assigns @user" do
46 | User.stub(:find).and_return(user)
47 |
48 | get :show, :id => user.id
49 | assigns[:user].should eq(user)
50 | end
51 |
52 | it "assigns only current user to @user" do
53 | another_user = mock_model(User)
54 | User.stub(:find).and_return(another_user)
55 |
56 | get :show, :id => another_user.id
57 | assigns[:user].should eq(user)
58 | end
59 | end
60 |
61 | describe "PUT approve" do
62 | let(:another_user) { mock_model(User) }
63 |
64 | before do
65 | another_user.stub(:approve!).and_return(another_user)
66 | User.stub(:find).and_return(another_user)
67 | end
68 |
69 | it "assigns @user" do
70 | put :approve, :id => another_user.id
71 | assigns[:user].should eq(another_user)
72 | end
73 |
74 | it "approves user" do
75 | another_user.should_receive(:approve!)
76 | put :approve, :id => another_user.id
77 | end
78 |
79 | it "redirects to users URL" do
80 | put :approve, :id => another_user.id
81 | response.should redirect_to(users_url)
82 | end
83 |
84 | context "when user is not an admin" do
85 | before { user.stub(:admin?).and_return(false) }
86 |
87 | it "sets flash notice" do
88 | put :approve, :id => another_user.id
89 | flash[:notice].should_not be_blank
90 | end
91 |
92 | it "redirects to sign in URL" do
93 | put :approve, :id => another_user.id
94 | response.should redirect_to(sign_in_url)
95 | end
96 | end
97 | end
98 |
99 | describe "PUT unapprove" do
100 | let(:another_user) { mock_model(User) }
101 |
102 | before do
103 | another_user.stub(:unapprove!).and_return(another_user)
104 | User.stub(:find).and_return(another_user)
105 | end
106 |
107 | it "assigns @user" do
108 | put :unapprove, :id => another_user.id
109 | assigns[:user].should eq(another_user)
110 | end
111 |
112 | it "unapproves user" do
113 | another_user.should_receive(:unapprove!)
114 | put :unapprove, :id => another_user.id
115 | end
116 |
117 | it "redirects to users URL" do
118 | put :unapprove, :id => another_user.id
119 | response.should redirect_to(users_url)
120 | end
121 |
122 | context "when user is not an admin" do
123 | before { user.stub(:admin?).and_return(false) }
124 |
125 | it "sets flash notice" do
126 | put :unapprove, :id => another_user.id
127 | flash[:notice].should_not be_blank
128 | end
129 |
130 | it "redirects to sign in URL" do
131 | put :unapprove, :id => another_user.id
132 | response.should redirect_to(sign_in_url)
133 | end
134 | end
135 | end
136 |
137 | describe "DELETE destroy" do
138 | let(:another_user) { mock_model(User) }
139 |
140 | before do
141 | another_user.stub(:destroy).and_return(another_user)
142 | User.stub(:find).and_return(another_user)
143 | end
144 |
145 | it "assigns @user" do
146 | delete :destroy, :id => another_user.id
147 | assigns[:user].should eq(another_user)
148 | end
149 |
150 | it "destroy user" do
151 | another_user.should_receive(:destroy)
152 | delete :destroy, :id => another_user.id
153 | end
154 |
155 | context "when user is not an admin" do
156 | before { user.stub(:admin?).and_return(false) }
157 |
158 | it "sets flash notice" do
159 | delete :destroy, :id => another_user.id
160 | flash[:notice].should_not be_blank
161 | end
162 |
163 | it "redirects to sign in URL" do
164 | delete :destroy, :id => another_user.id
165 | response.should redirect_to(sign_in_url)
166 | end
167 | end
168 | end
169 | end
170 |
--------------------------------------------------------------------------------
/public/markdown-reference/es/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Guía de Markdown
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Guía de Markdown
13 |
14 | Texto
15 |
16 |
17 |
18 |
19 | Markdown
20 | Resultado
21 |
22 |
23 | Este texto está en **negrita**.
24 | Este texto está en negrita .
25 |
26 |
27 | Este texto está en *cursiva*.
28 | Este texto está en cursiva .
29 |
30 |
31 | `Esto es un trozo de código.`
32 | Esto es un trozo de código.
33 |
34 |
35 |
36 |
37 | Encabezados
38 |
39 |
40 |
41 |
42 | Markdown
43 | Resultado
44 |
45 |
46 | # Primer encabezado
47 | Primer encabezado
48 |
49 |
50 | ## Segundo encabezado
51 | Segundo encabezado
52 |
53 |
54 | ### Tercer encabezado
55 | Tercer encabezado
56 |
57 |
58 |
59 |
60 | Citas
61 |
62 |
63 |
64 |
65 |
66 | > Este es el primer nivel de la cita.
67 | >> Esto es una cita anidada
68 | > Vuelta al primer nivel.
69 |
70 |
71 |
72 | Este es el primer nivel de la cita.
73 |
74 | Esto es una cita anidada.
75 |
76 | Vuelta al primer nivel.
77 |
78 |
79 |
80 |
81 |
82 |
83 | Enlaces y imágenes
84 |
85 |
86 |
87 |
88 | Enlace a [Google](http://google.com).
89 | Enlace a Google .
90 |
91 |
92 | Envíame un correo a <direccion@ejemplo.com>.
93 | Envíame un correo a direccion@ejemplo.com .
94 |
95 |
96 | 
97 |
98 |
99 |
100 |
101 |
102 | Listas
103 |
104 |
105 |
106 |
107 | Markdown
108 | Resultado
109 |
110 |
111 |
112 | * Leche
113 | * Pan
114 | * Queso
115 | * Gruyere
116 | * Camembert
117 | * Arroz
118 |
119 |
120 |
121 | Leche
122 | Pan
123 | Queso
124 |
125 | Gruyere
126 | Camembert
127 |
128 |
129 | Arroz
130 |
131 |
132 |
133 |
134 |
135 | 1. Leche
136 | 2. Pan
137 | 3. Queso
138 | 1. Gruyere
139 | 2. Camembert
140 | 3. Arroz
141 |
142 |
143 |
144 | Leche
145 | Pan
146 | Queso
147 |
148 | Gruyere
149 | Camembert
150 |
151 |
152 | Arroz
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
--------------------------------------------------------------------------------
/config/locales/active_support.yml:
--------------------------------------------------------------------------------
1 | # Russian localization for Ruby on Rails 2.2+
2 | # by Yaroslav Markin
3 | #
4 | # Be sure to check out "russian" gem (http://github.com/yaroslav/russian) for
5 | # full Russian language support in Rails (month names, pluralization, etc).
6 | # The following is an excerpt from that gem.
7 | #
8 | # Для полноценной поддержки русского языка (варианты названий месяцев,
9 | # плюрализация и так далее) в Rails 2.2 нужно использовать gem "russian"
10 | # (http://github.com/yaroslav/russian). Следующие данные -- выдержка их него, чтобы
11 | # была возможность минимальной локализации приложения на русский язык.
12 |
13 | ru:
14 | date:
15 | formats:
16 | default: "%d.%m.%Y"
17 | short: "%d %b"
18 | long: "%d %B %Y"
19 |
20 | day_names: [воскресенье, понедельник, вторник, среда, четверг, пятница, суббота]
21 | standalone_day_names: [Воскресенье, Понедельник, Вторник, Среда, Четверг, Пятница, Суббота]
22 | abbr_day_names: [Вс, Пн, Вт, Ср, Чт, Пт, Сб]
23 |
24 | month_names: [~, января, февраля, марта, апреля, мая, июня, июля, августа, сентября, октября, ноября, декабря]
25 | # see russian gem for info on "standalone" day names
26 | standalone_month_names: [~, Январь, Февраль, Март, Апрель, Май, Июнь, Июль, Август, Сентябрь, Октябрь, Ноябрь, Декабрь]
27 | abbr_month_names: [~, янв., февр., марта, апр., мая, июня, июля, авг., сент., окт., нояб., дек.]
28 | standalone_abbr_month_names: [~, янв., февр., март, апр., май, июнь, июль, авг., сент., окт., нояб., дек.]
29 |
30 | order: [ ":day", ":month", ":year" ]
31 |
32 | time:
33 | formats:
34 | default: "%a, %d %b %Y, %H:%M:%S %z"
35 | short: "%d %b, %H:%M"
36 | long: "%d %B %Y, %H:%M"
37 |
38 | am: "утра"
39 | pm: "вечера"
40 |
41 | number:
42 | format:
43 | separator: "."
44 | delimiter: " "
45 | precision: 3
46 |
47 | currency:
48 | format:
49 | format: "%n %u"
50 | unit: "руб."
51 | separator: "."
52 | delimiter: " "
53 | precision: 2
54 |
55 | percentage:
56 | format:
57 | delimiter: ""
58 |
59 | precision:
60 | format:
61 | delimiter: ""
62 |
63 | human:
64 | format:
65 | delimiter: ""
66 | precision: 1
67 | # Rails 2.2
68 | # storage_units: [байт, КБ, МБ, ГБ, ТБ]
69 |
70 | # Rails 2.3
71 | storage_units:
72 | # Storage units output formatting.
73 | # %u is the storage unit, %n is the number (default: 2 MB)
74 | format: "%n %u"
75 | units:
76 | byte:
77 | one: "байт"
78 | few: "байта"
79 | many: "байт"
80 | other: "байта"
81 | kb: "КБ"
82 | mb: "МБ"
83 | gb: "ГБ"
84 | tb: "ТБ"
85 |
86 | datetime:
87 | distance_in_words:
88 | half_a_minute: "меньше минуты"
89 | less_than_x_seconds:
90 | one: "меньше %{count} секунды"
91 | few: "меньше %{count} секунд"
92 | many: "меньше %{count} секунд"
93 | other: "меньше %{count} секунды"
94 | x_seconds:
95 | one: "%{count} секунда"
96 | few: "%{count} секунды"
97 | many: "%{count} секунд"
98 | other: "%{count} секунды"
99 | less_than_x_minutes:
100 | one: "меньше %{count} минуты"
101 | few: "меньше %{count} минут"
102 | many: "меньше %{count} минут"
103 | other: "меньше %{count} минуты"
104 | x_minutes:
105 | one: "%{count} минуту"
106 | few: "%{count} минуты"
107 | many: "%{count} минут"
108 | other: "%{count} минуты"
109 | about_x_hours:
110 | one: "около %{count} часа"
111 | few: "около %{count} часов"
112 | many: "около %{count} часов"
113 | other: "около %{count} часа"
114 | x_days:
115 | one: "%{count} день"
116 | few: "%{count} дня"
117 | many: "%{count} дней"
118 | other: "%{count} дня"
119 | about_x_months:
120 | one: "около %{count} месяца"
121 | few: "около %{count} месяцев"
122 | many: "около %{count} месяцев"
123 | other: "около %{count} месяца"
124 | x_months:
125 | one: "%{count} месяц"
126 | few: "%{count} месяца"
127 | many: "%{count} месяцев"
128 | other: "%{count} месяца"
129 | about_x_years:
130 | one: "около %{count} года"
131 | few: "около %{count} лет"
132 | many: "около %{count} лет"
133 | other: "около %{count} лет"
134 | over_x_years:
135 | one: "больше %{count} года"
136 | few: "больше %{count} лет"
137 | many: "больше %{count} лет"
138 | other: "больше %{count} лет"
139 | prompts:
140 | year: "Год"
141 | month: "Месяц"
142 | day: "День"
143 | hour: "Часов"
144 | minute: "Минут"
145 | second: "Секунд"
146 |
147 | select:
148 | # default value for :prompt => true in FormOptionsHelper
149 | prompt: "Выберите: "
150 | support:
151 | array:
152 | # Rails 2.2
153 | sentence_connector: "и"
154 | skip_last_comma: true
155 |
156 | # Rails 2.3
157 | words_connector: ", "
158 | two_words_connector: " и "
159 | last_word_connector: " и "
160 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GIT
2 | remote: git://github.com/nadarei/mina.git
3 | revision: 8248fba1222ac4da7f73d422c9a71e99e23df957
4 | specs:
5 | mina (0.2.1)
6 | open4
7 | rake
8 |
9 | GEM
10 | remote: https://rubygems.org/
11 | specs:
12 | actionmailer (3.2.13)
13 | actionpack (= 3.2.13)
14 | mail (~> 2.5.3)
15 | actionpack (3.2.13)
16 | activemodel (= 3.2.13)
17 | activesupport (= 3.2.13)
18 | builder (~> 3.0.0)
19 | erubis (~> 2.7.0)
20 | journey (~> 1.0.4)
21 | rack (~> 1.4.5)
22 | rack-cache (~> 1.2)
23 | rack-test (~> 0.6.1)
24 | sprockets (~> 2.2.1)
25 | activemodel (3.2.13)
26 | activesupport (= 3.2.13)
27 | builder (~> 3.0.0)
28 | activerecord (3.2.13)
29 | activemodel (= 3.2.13)
30 | activesupport (= 3.2.13)
31 | arel (~> 3.0.2)
32 | tzinfo (~> 0.3.29)
33 | activeresource (3.2.13)
34 | activemodel (= 3.2.13)
35 | activesupport (= 3.2.13)
36 | activesupport (3.2.13)
37 | i18n (= 0.6.1)
38 | multi_json (~> 1.0)
39 | arel (3.0.2)
40 | bugsnag (1.3.6)
41 | httparty (>= 0.6, < 1.0)
42 | multi_json (~> 1.0)
43 | builder (3.0.4)
44 | cancan (1.6.9)
45 | diff-lcs (1.2.4)
46 | dotenv (0.7.0)
47 | erubis (2.7.0)
48 | execjs (1.4.0)
49 | multi_json (~> 1.0)
50 | factory_girl (4.2.0)
51 | activesupport (>= 3.0.0)
52 | factory_girl_rails (4.2.1)
53 | factory_girl (~> 4.2.0)
54 | railties (>= 3.0.0)
55 | faraday (0.8.7)
56 | multipart-post (~> 1.1)
57 | figaro (0.6.4)
58 | bundler (~> 1.0)
59 | rails (>= 3, < 5)
60 | foreman (0.63.0)
61 | dotenv (>= 0.7)
62 | thor (>= 0.13.6)
63 | hashie (2.0.4)
64 | hike (1.2.2)
65 | httparty (0.11.0)
66 | multi_json (~> 1.0)
67 | multi_xml (>= 0.5.2)
68 | httpauth (0.2.0)
69 | i18n (0.6.1)
70 | journey (1.0.4)
71 | jquery-rails (2.2.1)
72 | railties (>= 3.0, < 5.0)
73 | thor (>= 0.14, < 2.0)
74 | json (1.8.3)
75 | jwt (0.1.8)
76 | multi_json (>= 1.5)
77 | kaminari (0.14.1)
78 | actionpack (>= 3.0.0)
79 | activesupport (>= 3.0.0)
80 | kgio (2.11.0)
81 | libv8 (3.16.14.17)
82 | mail (2.5.3)
83 | i18n (>= 0.4.0)
84 | mime-types (~> 1.16)
85 | treetop (~> 1.4.8)
86 | mime-types (1.23)
87 | multi_json (1.7.2)
88 | multi_xml (0.5.3)
89 | multipart-post (1.2.0)
90 | newrelic_rpm (3.6.1.88)
91 | oauth (0.4.7)
92 | oauth2 (0.8.1)
93 | faraday (~> 0.8)
94 | httpauth (~> 0.1)
95 | jwt (~> 0.1.4)
96 | multi_json (~> 1.0)
97 | rack (~> 1.2)
98 | omniauth (1.1.4)
99 | hashie (>= 1.2, < 3)
100 | rack
101 | omniauth-github (1.1.0)
102 | omniauth (~> 1.0)
103 | omniauth-oauth2 (~> 1.1)
104 | omniauth-oauth (1.0.1)
105 | oauth
106 | omniauth (~> 1.0)
107 | omniauth-oauth2 (1.1.1)
108 | oauth2 (~> 0.8.0)
109 | omniauth (~> 1.0)
110 | omniauth-openid (1.0.1)
111 | omniauth (~> 1.0)
112 | rack-openid (~> 1.3.1)
113 | omniauth-twitter (0.0.16)
114 | multi_json (~> 1.3)
115 | omniauth-oauth (~> 1.0)
116 | open4 (1.3.0)
117 | pg (0.15.1)
118 | polyglot (0.3.3)
119 | rack (1.4.5)
120 | rack-cache (1.2)
121 | rack (>= 0.4)
122 | rack-openid (1.3.1)
123 | rack (>= 1.1.0)
124 | ruby-openid (>= 2.1.8)
125 | rack-ssl (1.3.3)
126 | rack
127 | rack-test (0.6.2)
128 | rack (>= 1.0)
129 | rails (3.2.13)
130 | actionmailer (= 3.2.13)
131 | actionpack (= 3.2.13)
132 | activerecord (= 3.2.13)
133 | activeresource (= 3.2.13)
134 | activesupport (= 3.2.13)
135 | bundler (~> 1.0)
136 | railties (= 3.2.13)
137 | railties (3.2.13)
138 | actionpack (= 3.2.13)
139 | activesupport (= 3.2.13)
140 | rack-ssl (~> 1.3.2)
141 | rake (>= 0.8.7)
142 | rdoc (~> 3.4)
143 | thor (>= 0.14.6, < 2.0)
144 | raindrops (0.17.0)
145 | rake (10.0.4)
146 | rdiscount (2.0.7.2)
147 | rdoc (3.12.2)
148 | json (~> 1.4)
149 | ref (2.0.0)
150 | rspec-core (2.13.1)
151 | rspec-expectations (2.13.0)
152 | diff-lcs (>= 1.1.3, < 2.0)
153 | rspec-mocks (2.13.1)
154 | rspec-rails (2.13.1)
155 | actionpack (>= 3.0)
156 | activesupport (>= 3.0)
157 | railties (>= 3.0)
158 | rspec-core (~> 2.13.0)
159 | rspec-expectations (~> 2.13.0)
160 | rspec-mocks (~> 2.13.0)
161 | ruby-openid (2.2.3)
162 | sprockets (2.2.2)
163 | hike (~> 1.2)
164 | multi_json (~> 1.0)
165 | rack (~> 1.0)
166 | tilt (~> 1.1, != 1.3.0)
167 | textacular (3.0.0)
168 | activerecord (>= 3.0, < 4.1)
169 | therubyracer (0.12.2)
170 | libv8 (~> 3.16.14.0)
171 | ref
172 | thor (0.18.1)
173 | tilt (1.4.0)
174 | treetop (1.4.12)
175 | polyglot
176 | polyglot (>= 0.3.1)
177 | tzinfo (0.3.37)
178 | uglifier (2.0.1)
179 | execjs (>= 0.3.0)
180 | multi_json (~> 1.0, >= 1.0.2)
181 | unicorn (4.6.2)
182 | kgio (~> 2.6)
183 | rack
184 | raindrops (~> 0.7)
185 |
186 | PLATFORMS
187 | ruby
188 |
189 | DEPENDENCIES
190 | bugsnag (~> 1.3.6)
191 | cancan (~> 1.6.9)
192 | factory_girl_rails (~> 4.2.1)
193 | figaro (~> 0.6.4)
194 | foreman (~> 0.63.0)
195 | jquery-rails (~> 2.2.1)
196 | kaminari (~> 0.14.1)
197 | mina!
198 | newrelic_rpm (~> 3.6.1.88)
199 | omniauth (~> 1.1.4)
200 | omniauth-github (~> 1.1.0)
201 | omniauth-openid (~> 1.0.1)
202 | omniauth-twitter (~> 0.0.16)
203 | pg (~> 0.15.1)
204 | rails (~> 3.2.13)
205 | rdiscount (~> 2.0.7.2)
206 | rspec-rails (~> 2.13.1)
207 | textacular (~> 3.0.0)
208 | therubyracer (~> 0.12.2)
209 | uglifier (~> 2.0.1)
210 | unicorn (~> 4.6.2)
211 |
212 | BUNDLED WITH
213 | 1.13.7
214 |
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | " />
6 | " />
7 | " />
8 |
9 |
10 | <%= stylesheet_link_tag "application" %>
11 | <%= csrf_meta_tag %>
12 | <%= "#{yield(:title)} — ".html_safe unless yield(:title).blank? -%><%= t('.title') -%>
13 |
27 |
28 |
35 |
36 |
37 |
38 | <% if can?(:manage, :all) %>
39 |
40 |
41 | <%= link_to t(".users"), users_url %>
42 |
43 |
44 | <% end %>
45 |
70 |
73 |
96 | <%= javascript_include_tag "application" %>
97 |
100 | <%= yield(:footer_js) %>
101 |
102 | <% if Rails.env.production? %>
103 | <%= javascript_include_tag "http://static.evernote.com/noteit.js", :cache => false %>
104 |
115 | <% end %>
116 |
117 |
118 |
--------------------------------------------------------------------------------
/vendor/assets/stylesheets/960gs.css:
--------------------------------------------------------------------------------
1 | /* Containers
2 | ----------------------------------------------------------------------------------------------------*/
3 | .container_12 {
4 | margin-left: auto;
5 | margin-right: auto;
6 | width: 960px;
7 | }
8 |
9 | /* Grid >> Children (Alpha ~ First, Omega ~ Last)
10 | ----------------------------------------------------------------------------------------------------*/
11 |
12 | .alpha {
13 | margin-left: 0 !important;
14 | }
15 |
16 | .omega {
17 | margin-right: 0 !important;
18 | }
19 |
20 |
21 |
22 | /* Grid >> Global
23 | ----------------------------------------------------------------------------------------------------*/
24 |
25 | .grid_1,
26 | .grid_2,
27 | .grid_3,
28 | .grid_4,
29 | .grid_5,
30 | .grid_6,
31 | .grid_7,
32 | .grid_8,
33 | .grid_9,
34 | .grid_10,
35 | .grid_11,
36 | .grid_12{
37 | display:inline;
38 | float: left;
39 | position: relative;
40 | margin-left: 10.0px;
41 | margin-right: 10.0px;
42 | }
43 |
44 |
45 | /* Grid >> 2 Columns
46 | ----------------------------------------------------------------------------------------------------*/
47 |
48 | .container_12 .grid_1{
49 | width:60px;
50 | }
51 |
52 | .container_12 .grid_2{
53 | width:140px;
54 | }
55 |
56 | .container_12 .grid_3{
57 | width:220px;
58 | }
59 |
60 | .container_12 .grid_4{
61 | width:300px;
62 | }
63 |
64 | .container_12 .grid_5{
65 | width:380px;
66 | }
67 |
68 | .container_12 .grid_6{
69 | width:460px;
70 | }
71 |
72 | .container_12 .grid_7{
73 | width:540px;
74 | }
75 |
76 | .container_12 .grid_8{
77 | width:620px;
78 | }
79 |
80 | .container_12 .grid_9{
81 | width:700px;
82 | }
83 |
84 | .container_12 .grid_10{
85 | width:780px;
86 | }
87 |
88 | .container_12 .grid_11{
89 | width:860px;
90 | }
91 |
92 | .container_12 .grid_12{
93 | width:940px;
94 | }
95 |
96 |
97 |
98 |
99 |
100 | /* Prefix Extra Space >> 2 Columns
101 | ----------------------------------------------------------------------------------------------------*/
102 |
103 | .container_12 .prefix_1 {
104 | padding-left:80px;
105 | }
106 |
107 | .container_12 .prefix_2 {
108 | padding-left:160px;
109 | }
110 |
111 | .container_12 .prefix_3 {
112 | padding-left:240px;
113 | }
114 |
115 | .container_12 .prefix_4 {
116 | padding-left:320px;
117 | }
118 |
119 | .container_12 .prefix_5 {
120 | padding-left:400px;
121 | }
122 |
123 | .container_12 .prefix_6 {
124 | padding-left:480px;
125 | }
126 |
127 | .container_12 .prefix_7 {
128 | padding-left:560px;
129 | }
130 |
131 | .container_12 .prefix_8 {
132 | padding-left:640px;
133 | }
134 |
135 | .container_12 .prefix_9 {
136 | padding-left:720px;
137 | }
138 |
139 | .container_12 .prefix_10 {
140 | padding-left:800px;
141 | }
142 |
143 | .container_12 .prefix_11 {
144 | padding-left:880px;
145 | }
146 |
147 |
148 |
149 | /* Suffix Extra Space >> 2 Columns
150 | ----------------------------------------------------------------------------------------------------*/
151 |
152 | .container_12 .suffix_1 {
153 | padding-right:80px;
154 | }
155 |
156 | .container_12 .suffix_2 {
157 | padding-right:160px;
158 | }
159 |
160 | .container_12 .suffix_3 {
161 | padding-right:240px;
162 | }
163 |
164 | .container_12 .suffix_4 {
165 | padding-right:320px;
166 | }
167 |
168 | .container_12 .suffix_5 {
169 | padding-right:400px;
170 | }
171 |
172 | .container_12 .suffix_6 {
173 | padding-right:480px;
174 | }
175 |
176 | .container_12 .suffix_7 {
177 | padding-right:560px;
178 | }
179 |
180 | .container_12 .suffix_8 {
181 | padding-right:640px;
182 | }
183 |
184 | .container_12 .suffix_9 {
185 | padding-right:720px;
186 | }
187 |
188 | .container_12 .suffix_10 {
189 | padding-right:800px;
190 | }
191 |
192 | .container_12 .suffix_11 {
193 | padding-right:880px;
194 | }
195 |
196 |
197 |
198 | /* Push Space >> 2 Columns
199 | ----------------------------------------------------------------------------------------------------*/
200 |
201 | .container_12 .push_1 {
202 | left:80px;
203 | }
204 |
205 | .container_12 .push_2 {
206 | left:160px;
207 | }
208 |
209 | .container_12 .push_3 {
210 | left:240px;
211 | }
212 |
213 | .container_12 .push_4 {
214 | left:320px;
215 | }
216 |
217 | .container_12 .push_5 {
218 | left:400px;
219 | }
220 |
221 | .container_12 .push_6 {
222 | left:480px;
223 | }
224 |
225 | .container_12 .push_7 {
226 | left:560px;
227 | }
228 |
229 | .container_12 .push_8 {
230 | left:640px;
231 | }
232 |
233 | .container_12 .push_9 {
234 | left:720px;
235 | }
236 |
237 | .container_12 .push_10 {
238 | left:800px;
239 | }
240 |
241 | .container_12 .push_11 {
242 | left:880px;
243 | }
244 |
245 |
246 |
247 |
248 |
249 | /* Pull Space >> 2 Columns
250 | ----------------------------------------------------------------------------------------------------*/
251 |
252 | .container_12 .pull_1 {
253 | right:80px;
254 | }
255 |
256 | .container_12 .pull_2 {
257 | right:160px;
258 | }
259 |
260 | .container_12 .pull_3 {
261 | right:240px;
262 | }
263 |
264 | .container_12 .pull_4 {
265 | right:320px;
266 | }
267 |
268 | .container_12 .pull_5 {
269 | right:400px;
270 | }
271 |
272 | .container_12 .pull_6 {
273 | right:480px;
274 | }
275 |
276 | .container_12 .pull_7 {
277 | right:560px;
278 | }
279 |
280 | .container_12 .pull_8 {
281 | right:640px;
282 | }
283 |
284 | .container_12 .pull_9 {
285 | right:720px;
286 | }
287 |
288 | .container_12 .pull_10 {
289 | right:800px;
290 | }
291 |
292 | .container_12 .pull_11 {
293 | right:880px;
294 | }
295 |
296 |
297 |
298 |
299 | /* Clear Floated Elements
300 | ----------------------------------------------------------------------------------------------------*/
301 |
302 |
303 | .clear {
304 | clear: both;
305 | display: block;
306 | overflow: hidden;
307 | visibility: hidden;
308 | width: 0;
309 | height: 0;
310 | }
311 |
312 |
313 | .clearfix:after {
314 | clear: both;
315 | content: ' ';
316 | display: block;
317 | font-size: 0;
318 | line-height: 0;
319 | visibility: hidden;
320 | width: 0;
321 | height: 0;
322 | }
323 |
324 | .clearfix {
325 | display: inline-block;
326 | }
327 |
328 | * html .clearfix {
329 | height: 1%;
330 | }
331 |
332 | .clearfix {
333 | display: block;
334 | }
--------------------------------------------------------------------------------
/spec/controllers/items_controller_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe ItemsController do
4 | let(:user) { mock_model(User, :admin? => false, :guest? => false) }
5 | let(:item) { mock_model(Item).as_null_object }
6 |
7 | before { controller.stub(:current_user).and_return(user) }
8 |
9 | describe "GET index" do
10 | it "assigns @items" do
11 | Item.stub_chain(:recent, :page, :per).and_return([item])
12 | get :index
13 | assigns[:items].should eq([item])
14 | end
15 | end
16 |
17 | describe "GET new" do
18 | before { user.stub_chain(:items, :new).and_return(item) }
19 |
20 | it "creates a new item" do
21 | user.items.should_receive(:new)
22 | get :new
23 | end
24 |
25 | it "assigns @item" do
26 | get :new
27 | assigns[:item].should eq(item)
28 | end
29 |
30 | context "when user is a guest" do
31 | before { controller.stub(:current_user).and_return(nil) }
32 |
33 | it "sets flash notice" do
34 | get :new
35 | flash[:notice].should_not be_blank
36 | end
37 |
38 | it "redirects to sign in URL" do
39 | get :new
40 | response.should redirect_to(sign_in_url)
41 | end
42 | end
43 | end
44 |
45 | describe "POST create" do
46 | before { user.stub_chain(:items, :create).and_return(item) }
47 |
48 | it "creates a new item" do
49 | user.items.should_receive(:create)
50 | post :create
51 | end
52 |
53 | it "redirects to item URL" do
54 | post :create
55 | response.should redirect_to(item_url(item))
56 | end
57 |
58 | context "when user is a guest" do
59 | before { controller.stub(:current_user).and_return(nil) }
60 |
61 | it "sets flash notice" do
62 | get :new
63 | flash[:notice].should_not be_blank
64 | end
65 |
66 | it "redirects to sign in URL" do
67 | get :new
68 | response.should redirect_to(sign_in_url)
69 | end
70 | end
71 | end
72 |
73 | describe "GET show" do
74 | before { Item.stub(:find).and_return(item) }
75 |
76 | it "assigns @item" do
77 | get :show, :id => item.id
78 | assigns[:item].should eq(item)
79 | end
80 | end
81 |
82 | describe "GET edit" do
83 | before { Item.stub(:find).and_return(item) }
84 |
85 | it "assigns @item" do
86 | get :edit, :id => item.id
87 | assigns[:item].should eq(item)
88 | end
89 |
90 | context "when user is a guest" do
91 | before { controller.stub(:current_user).and_return(nil) }
92 |
93 | it "sets flash notice" do
94 | get :edit, :id => item.id
95 | flash[:notice].should_not be_blank
96 | end
97 |
98 | it "redirects to sign in URL" do
99 | get :edit, :id => item.id
100 | response.should redirect_to(sign_in_url)
101 | end
102 | end
103 |
104 | context "when user is not an author" do
105 | before do
106 | item.stub(:author?).and_return(false)
107 | end
108 |
109 | it "sets flash notice" do
110 | get :edit, :id => item.id
111 | flash[:notice].should_not be_blank
112 | end
113 |
114 | it "redirects to sign in URL" do
115 | get :edit, :id => item.id
116 | response.should redirect_to(sign_in_url)
117 | end
118 | end
119 | end
120 |
121 | describe "GET show" do
122 | before { Item.stub(:find).and_return(item) }
123 |
124 | it "assigns @item" do
125 | get :show, :id => item.id
126 | assigns[:item].should eq(item)
127 | end
128 | end
129 |
130 | describe "PUT update" do
131 | let(:attributes) { { "title" => "Foo" } }
132 | before { Item.stub(:find).and_return(item) }
133 |
134 | it "assigns @item" do
135 | put :update, :id => item.id
136 | assigns[:item].should eq(item)
137 | end
138 |
139 | it "updates item" do
140 | item.should_receive(:update_attributes).with(attributes)
141 | put :update, :id => item.id, :item => attributes
142 | end
143 |
144 | it "redirects to item url" do
145 | put :update, :id => item.id
146 | response.should redirect_to(item_url(item))
147 | end
148 |
149 | context "when user is a guest" do
150 | before { controller.stub(:current_user).and_return(nil) }
151 |
152 | it "sets flash notice" do
153 | put :update, :id => item.id
154 | flash[:notice].should_not be_blank
155 | end
156 |
157 | it "redirects to sign in URL" do
158 | put :update, :id => item.id
159 | response.should redirect_to(sign_in_url)
160 | end
161 | end
162 |
163 | context "when user is not an author" do
164 | before do
165 | item.stub(:author?).and_return(false)
166 | end
167 |
168 | it "sets flash notice" do
169 | put :update, :id => item.id
170 | flash[:notice].should_not be_blank
171 | end
172 |
173 | it "redirects to sign in URL" do
174 | put :update, :id => item.id
175 | response.should redirect_to(sign_in_url)
176 | end
177 | end
178 | end
179 |
180 | describe "DELETE destroy" do
181 | before { Item.stub(:find).and_return(item) }
182 |
183 | context "when user is an admin" do
184 | before { user.stub(:admin?).and_return(true) }
185 |
186 | it "assigns @item" do
187 | delete :destroy, :id => item.id
188 | assigns[:item].should eq(item)
189 | end
190 |
191 | it "destroy item" do
192 | item.should_receive(:destroy)
193 | delete :destroy, :id => item.id
194 | end
195 |
196 | it "redirects to items url" do
197 | delete :destroy, :id => item.id
198 | response.should redirect_to(items_url)
199 | end
200 | end
201 |
202 | context "when user is not an admin but author" do
203 | before { item.stub(:author?).and_return(true) }
204 |
205 | it "assigns @item" do
206 | delete :destroy, :id => item.id
207 | assigns[:item].should eq(item)
208 | end
209 |
210 | it "destroy item" do
211 | item.should_receive(:destroy)
212 | delete :destroy, :id => item.id
213 | end
214 |
215 | it "sets flash notice" do
216 | delete :destroy, :id => item.id
217 | flash[:notice].should_not be_blank
218 | end
219 |
220 | it "redirects to sign in URL" do
221 | delete :destroy, :id => item.id
222 | response.should redirect_to(items_url)
223 | end
224 | end
225 |
226 | context "when user is a guest" do
227 | before { controller.stub(:current_user).and_return(nil) }
228 |
229 | it "sets flash notice" do
230 | delete :destroy, :id => item.id
231 | flash[:notice].should_not be_blank
232 | end
233 |
234 | it "redirects to sign in URL" do
235 | delete :destroy, :id => item.id
236 | response.should redirect_to(sign_in_url)
237 | end
238 | end
239 |
240 | context "when user is not an admin and not author" do
241 | before { item.stub(:author?).and_return(false) }
242 |
243 | it "sets flash notice" do
244 | delete :destroy, :id => item.id
245 | flash[:notice].should_not be_blank
246 | end
247 |
248 | it "redirects to sign in URL" do
249 | delete :destroy, :id => item.id
250 | response.should redirect_to(sign_in_url)
251 | end
252 | end
253 | end
254 | end
255 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | *= require reset
3 | *= require 960gs
4 | *= require form
5 | *= require wmd
6 | *= require code
7 | *= require_self
8 | */
9 |
10 | /* ------------------------------------------------------------------------
11 | = Page
12 | ------------------------------------------------------------------------ */
13 | body {
14 | font-family: Helvetica, Arial, sans-serif;
15 | font-size:14px;
16 | line-height:21px;
17 | color:#444;
18 | }
19 | h1 {
20 | margin-bottom:1em;
21 | padding:0;
22 | border:none;
23 | font-size:22px;
24 | font-weight:bold;
25 | }
26 | h2 {
27 | font-size:14px;
28 | font-weight:bold;
29 | margin-bottom:1em;
30 | }
31 | h1, h2, h3, h4, p { word-wrap:break-word; }
32 | article header a {
33 | color:#444;
34 | text-decoration:none;
35 | }
36 | strong {
37 | font-weight:bold;
38 | }
39 | p,
40 | pre,
41 | ul,
42 | ol {
43 | margin-bottom:1em;
44 | }
45 | ul, ol {
46 | padding-left:1.5em;
47 | }
48 | ul {
49 | list-style-type:circle;
50 | }
51 | ol {
52 | list-style-type:decimal;
53 | }
54 | ul li {
55 | list-style:disc outside none;
56 | }
57 | .providers {
58 | padding:0;
59 | font-weight:bold;
60 | }
61 | .providers li {
62 | display:inline-block;
63 | margin-right:2em;
64 | list-style:none outside none;
65 | }
66 | .providers a {
67 | text-decoration:none;
68 | }
69 | .providers img {
70 | vertical-align:middle;
71 | }
72 | em {
73 | font-style:italic;
74 | }
75 |
76 | article header a:hover,
77 | a {
78 | color:#758EA2;
79 | }
80 | a:hover {
81 | color:#5b6e7e;
82 | }
83 | .link-with-icon {
84 | text-decoration:none;
85 | text-transform:uppercase;
86 | line-height:16px;
87 | color:#444;
88 | font-size:11px;
89 | font-style:normal;
90 | }
91 | .link-with-icon .icon {
92 | margin-right:4px;
93 | }
94 | .uppercase {
95 | text-transform:uppercase;
96 | }
97 | /* ------------------------------------------------------------------------
98 | = Flash message
99 | ------------------------------------------------------------------------ */
100 | .flash {
101 | position:fixed;
102 | top:0;
103 | left:0;
104 | width:100%;
105 | z-index: 10000;
106 | border-bottom:2px solid rgba(0, 0, 0, 0.05);
107 | background-color:rgba(46, 46, 46, 0.95);
108 | }
109 | .flash .notice,
110 | .flash .error {
111 | margin:0 7%;
112 | padding:15px;
113 | font-size:14px;
114 | font-weight:bold;
115 | text-align:center;
116 | color:#FFF;
117 | }
118 | .flash .error { color:#CF3C25; }
119 |
120 | /* ------------------------------------------------------------------------
121 | = Control panel
122 | ------------------------------------------------------------------------ */
123 | #control-panel {
124 | border-bottom-right-radius:5px;
125 | border-bottom-left-radius:5px;
126 | background-color:#444;
127 | color:#CCC;
128 | font-size:11px;
129 | }
130 | #control-panel a {
131 | color:inherit;
132 | text-decoration:none;
133 | }
134 | #control-panel a:hover {
135 | color:#FFF;
136 | }
137 | #control-panel ul {
138 | margin:0;
139 | }
140 | #control-panel ul li {
141 | display:inline-block;
142 | list-style:none outside none;
143 | }
144 | /* ------------------------------------------------------------------------
145 | = Header
146 | ------------------------------------------------------------------------ */
147 | #header {
148 | position:relative;
149 | padding:24px 0;
150 | }
151 | /* http://www.colourlovers.com/palette/1388735/Diversion_II */
152 | #header .logo {
153 | color:#000;
154 | font-size:22px;
155 | font-weight:bold;
156 | }
157 | #header .logo a {
158 | text-decoration:none;
159 | color:#000;
160 | }
161 | #header .logo span {
162 | border-radius:5px;
163 | margin-left:2px;
164 | padding:1px 4px;
165 | background-color:#CF3C25;
166 | -background-color:#C1DE4B;
167 | color:#FFF;
168 | text-shadow:0 1px 1px rgba(0, 0, 0, 0.3);
169 | }
170 | #header .search {
171 | text-align:right;
172 | }
173 | #header .search input {
174 | width:100%;
175 | }
176 | #header .account {
177 | position:absolute;
178 | right:20px;
179 | top:0;
180 | padding:4px 8px;
181 | -webkit-border-bottom-right-radius: 5px;
182 | -webkit-border-bottom-left-radius: 5px;
183 | -moz-border-radius-bottomright: 5px;
184 | -moz-border-radius-bottomleft: 5px;
185 | border-bottom-right-radius: 5px;
186 | border-bottom-left-radius: 5px;
187 | background-color:#758EA2;
188 | font-size:11px;
189 | line-height:1;
190 | }
191 | #header .account a {
192 | color:#FFF;
193 | text-decoration:none;
194 | }
195 | #header .account a:hover {
196 | }
197 |
198 | #header .menu {
199 | text-align:right;
200 | text-transform:uppercase;
201 | font-size:12px;
202 | font-weight:bold;
203 | }
204 | #header .menu nav ul {
205 | padding-top:1px;
206 | }
207 | #header .menu nav ul li {
208 | display:inline-block;
209 | vertical-align:middle;
210 | padding:0 6px;
211 | line-height:1;
212 | }
213 | #header .menu nav a {
214 | display:inline-block;
215 | margin:0;
216 | padding:4px 9px;
217 | line-height:1;
218 | text-decoration:none;
219 | border-radius:10px;
220 | }
221 | #header .menu nav a:hover {
222 | color:#FFF;
223 | background-color:#CF3C25;
224 | }
225 |
226 | #content {
227 | margin-top:12px;
228 | }
229 | /* ------------------------------------------------------------------------
230 | = Event
231 | ------------------------------------------------------------------------ */
232 | .event {
233 | margin-bottom:2em;
234 | padding-bottom:1em;
235 | border-bottom:#CCC 1px dotted;
236 | }
237 | .event header {
238 | margin-bottom:1em;
239 | color:#CF3C25;
240 | font-weight:bold;
241 | line-height:1;
242 | }
243 | .event .list ul {
244 | margin:0;
245 | padding:0;
246 | color:#B2B2B2;
247 | font-size:10px;
248 | line-height:16px;
249 | }
250 | .event .list ul li {
251 | margin:0 0 4px 0;
252 | padding:4px 6px;
253 | list-style:none outside none;
254 | cursor:pointer;
255 | }
256 | .event .list ul li.current {
257 | -webkit-border-top-left-radius: 4px;
258 | -webkit-border-bottom-left-radius: 4px;
259 | -moz-border-radius-topleft: 4px;
260 | -moz-border-radius-bottomleft: 4px;
261 | border-top-left-radius: 4px;
262 | border-bottom-left-radius: 4px;
263 | background-color:#EEE;
264 | }
265 | .event .list ul li.current a {
266 | text-decoration:none;
267 | }
268 | .event .list ul header {
269 | margin:0;
270 | color:#444;
271 | font-size:14px;
272 | font-weight:bold;
273 | }
274 | .event .slide {
275 | margin:0;
276 | padding:0;
277 | color:#888;
278 | font-size:12px;
279 | line-height:18px;
280 | }
281 | .event .slide .banner {
282 | -webkit-border-radius: 4px;
283 | -moz-border-radius: 4px;
284 | border-radius: 4px;
285 | }
286 | .event .slide p,
287 | .event .slide pre,
288 | .event .slide ul,
289 | .event .slide ol {
290 | margin-bottom:6px;
291 | }
292 | /* ------------------------------------------------------------------------
293 | = Day
294 | ------------------------------------------------------------------------ */
295 | .day {}
296 | .day time {
297 | text-align:center;
298 | }
299 | time .date-day, time .date-month, time .date-year {
300 | color:#B2B2B2;
301 | font-weight:bold;
302 | line-height:1;
303 | }
304 | time .date-day {
305 | font-size:30px;
306 | }
307 | time .date-month {
308 | font-size:14px;
309 | }
310 | time .date-year {
311 | display:block;
312 | font-size:12px;
313 | }
314 | article {
315 | position:relative;
316 | margin-bottom:4em;
317 | }
318 | article header,
319 | .header-with-comment {
320 | margin-bottom:0.5em;
321 | padding:0;
322 | font-size:22px;
323 | font-weight:bold;
324 | }
325 | article header span,
326 | .header-with-comment span {
327 | display:block;
328 | margin-top:3px;
329 | padding-top:3px;
330 | line-height:1;
331 | font-size:12px;
332 | border-top:#CCC 1px solid;
333 | color:#B2B2B2;
334 | }
335 | article aside {
336 | position:absolute;
337 | top:0;
338 | right:0;
339 | display:none;
340 | }
341 | article:hover aside {
342 | display:block;
343 | }
344 | article aside ul li {
345 | margin:0 0 2px 0;
346 | padding:0;
347 | list-style:none outside none;
348 | line-height:1;
349 | }
350 | article img {
351 | max-width:620px;
352 | }
353 | article .comments {
354 | font-style:italic;
355 | }
356 | article .comments pre {
357 | font-style:normal;
358 | }
359 | article .comments .new-comment {
360 | display:none;
361 | }
362 | article .comments header {
363 | margin:0;
364 | padding:0;
365 | border:none;
366 | font-size:14px;
367 | }
368 | article .comments header a {
369 | color:#444;
370 | text-decoration:underline;
371 | }
372 | article .comments .comment {
373 | margin:0 0 1em 0;
374 | padding:0;
375 | }
376 | .comment header {}
377 | .comment header time {
378 | float:right;
379 | margin:0;
380 | padding:2px 4px;
381 | -webkit-border-radius:4px;
382 | -moz-border-radius:4px;
383 | border-radius:4px;
384 | color:#B2B2B2;
385 | -background-color:#758EA2;
386 | background-color:rgba(243, 246, 250, 1);
387 | font-weight:normal;
388 | font-size:11px;
389 | line-height:1;
390 | }
391 | .preview {
392 | position:relative;
393 | }
394 | .preview header,
395 | .comments .preview header {
396 | position:absolute;
397 | right:0;
398 | top:0;
399 | padding:0px 4px;
400 | -webkit-border-top-right-radius:5px;
401 | -webkit-border-bottom-left-radius:5px;
402 | -moz-border-radius-topright:5px;
403 | -moz-border-radius-bottomleft:5px;
404 | border-top-right-radius:5px;
405 | border-bottom-left-radius:5px;
406 | font-size:12px;
407 | font-weight:normal;
408 | font-style:normal;
409 | color:#FFF;
410 | background-color:rgba(207, 60, 37, 0.6);
411 | }
412 |
413 | .avatar {
414 | -webkit-border-radius:5px;
415 | -moz-border-radius:5px;
416 | border-radius:5px;
417 | }
418 |
419 | .users {
420 | margin-bottom:1em;
421 | }
422 | .users tr {
423 | margin:0;
424 | padding:0;
425 | border-bottom:#758EA2 1px solid;
426 | }
427 | .users tr:hover {
428 | background-color:rgba(243, 246, 250, 1);
429 | }
430 | .users td {
431 | margin:0;
432 | padding:3px;
433 | }
434 |
435 | .admin-buttons {
436 | padding:0;
437 | }
438 | .admin-buttons li {
439 | margin:0 1em 0 0;
440 | padding:0;
441 | list-style:none outside;
442 | }
443 | .pagination {
444 | text-align:center;
445 | }
446 | .pagination em {
447 | font-style:normal;
448 | font-size:22px;
449 | font-weight:bold;
450 | }
451 | .pagination a {
452 | display:inline-block;
453 | min-width:1em;
454 | padding:1px 3px;
455 | text-decoration:none;
456 | }
457 | .pagination a:hover {
458 | border-radius:5px;
459 | background-color:#CF3C25;
460 | color:#FFF;
461 | }
462 | .pagination .gap {}
463 | .pagination .previous_page {}
464 | .pagination .next_page {}
465 | .pagination .disabled {
466 | display:none;
467 | }
468 |
469 | .search-results {}
470 | .search-results h1 {
471 | color:#B2B2B2;
472 | }
473 | .search-results .counter {
474 | padding:4px 4px;
475 | border-radius:5px;
476 | background-color:#C1DE4B;
477 | color:#FFF;
478 | text-align:center;
479 | font-size:22px;
480 | }
481 |
482 | #footer {
483 | margin-top:100px;
484 | margin-bottom:30px;
485 | color:#444;
486 | font-size:11px;
487 | }
488 | #footer a {
489 | color:#444;
490 | }
491 | #footer .partner {
492 | text-decoration:none;
493 | }
494 | #footer .counters {
495 | text-align:center;
496 | }
497 | #footer p {
498 | margin-bottom:10px;
499 | line-height:14px;
500 | }
501 | #footer a span {
502 | padding:1px 3px;
503 | border-radius:2px;
504 | color:#fff;
505 | background-color:#758EA2;
506 | }
507 | #footer nav ul {
508 | text-align:right;
509 | text-transform:uppercase;
510 | font-size:9px;
511 | }
512 | #footer nav ul li {
513 | display:inline;
514 | margin-left:2em;
515 | }
516 | #footer nav a {}
517 | #footer nav a:hover {}
--------------------------------------------------------------------------------