diff --git a/Gemfile b/Gemfile index 00d86e9..ba7b4a9 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,4 @@ -source 'http://ruby.taobao.org/' +source 'https://ruby.taobao.org/' # Specify your gem's dependencies in file-part-upload.gemspec gemspec diff --git a/README.md b/README.md index 099a69c..6f343e2 100755 --- a/README.md +++ b/README.md @@ -263,4 +263,12 @@ lan_qiniu_compatibility_mode_upload_url: http://up.kc_file_upload.com = javascript_include_tag :application, :'data-turbolinks-track' => true ``` +# postgresql 如何使用方法 +## migrate +``` +# 生成所需数据表 +rails g active_record:file_part_upload whatever +rake db:migrate +``` +其余使用方法同上 diff --git a/app/models/concerns/file_part_upload/file_entity_active_record.rb b/app/models/concerns/file_part_upload/file_entity_active_record.rb new file mode 100644 index 0000000..e7c4146 --- /dev/null +++ b/app/models/concerns/file_part_upload/file_entity_active_record.rb @@ -0,0 +1,52 @@ +module FilePartUpload + module FileEntityActiveRecord + extend ActiveSupport::Concern + + KINDS = [:image, :audio, :video, :application, :text, :office, :pdf] + included do + extend Enumerize + + include FilePartUpload::QiniuValidate + include FilePartUpload::QiniuCreateMethods + include FilePartUpload::QiniuMethods + + # image video office + # field :kind, type: String + enumerize :kind, in: KINDS + + validates :original, :presence => true + validates :file_size, :presence => true + validates :mime, :presence => true + validates :kind, :presence => true + end + + class_methods do + end + + # 获取文件大小 + def file_size + meta_json["file_size"] + end + + def file_size=(p_file_size) + tmp = meta_json + tmp["file_size"] = p_file_size.to_i + self.meta = tmp.to_json + end + + KINDS.each do |kind_sym| + define_method "is_#{kind_sym}?" do + self.kind.to_s == kind_sym.to_s + end + end + + def meta_json + if meta.blank? + {} + else + JSON.parse meta + end + end + + end +end diff --git a/app/models/concerns/file_part_upload/file_entity_mongoid.rb b/app/models/concerns/file_part_upload/file_entity_mongoid.rb new file mode 100644 index 0000000..d729052 --- /dev/null +++ b/app/models/concerns/file_part_upload/file_entity_mongoid.rb @@ -0,0 +1,66 @@ +module FilePartUpload + module FileEntityMongoid + extend ActiveSupport::Concern + + KINDS = [:image, :audio, :video, :application, :text, :office, :pdf] + + included do + include Mongoid::Document + include Mongoid::Timestamps + extend Enumerize + + include FilePartUpload::QiniuValidate + include FilePartUpload::QiniuCreateMethods + include FilePartUpload::QiniuMethods + + # 原始文件名 + field :original, type: String + # content_type + field :mime, type: String + # image video office + # field :kind, type: String + enumerize :kind, in: KINDS + + # 本地模式 时, 表示 保存的文件名 + # qiniu模式 时, 表示 文件在七牛 bucket 中保存的 token(path) + field :token, type: String + + # 保存文件的 meta 信息 + # 所有文件都会有 {"file_size" => 1000} + # 具体特定文件的 meta 信息格式待确定 + field :meta, type: Hash + + # 只用于 本地模式 + # 表示已经保存的文件片段的大小 + field :saved_size, type: Integer + + # 只用于 本地模式 + # 表示是否已经把文件片段合并 + field :merged, type: Boolean, default: false + + + validates :original, :presence => true + validates :file_size, :presence => true + validates :mime, :presence => true + validates :kind, :presence => true + end + + # 获取文件大小 + def file_size + self.meta["file_size"] + end + + def file_size=(file_size) + self.meta = {} if self.meta.blank? + self.meta["file_size"] = file_size.to_i + end + + KINDS.each do |kind_sym| + define_method "is_#{kind_sym}?" do + self.kind.to_s == kind_sym.to_s + end + end + + + end +end diff --git a/app/models/concerns/file_part_upload/qiniu_create_methods.rb b/app/models/concerns/file_part_upload/qiniu_create_methods.rb index 7894d84..1444707 100755 --- a/app/models/concerns/file_part_upload/qiniu_create_methods.rb +++ b/app/models/concerns/file_part_upload/qiniu_create_methods.rb @@ -1,11 +1,8 @@ module FilePartUpload module QiniuCreateMethods - def self.included(base) - base.send(:extend, ClassMethods) - end - - module ClassMethods + extend ActiveSupport::Concern + class_methods do # { "bucket"=>"fushang318", # "token"=>"/i/yscPYbwk.jpeg", # "file_size"=>"3514", @@ -27,17 +24,27 @@ module ClassMethods # "avinfo_audio_duration" => "" # } def from_qiniu_callback_body(callback_body) + qiniu_base_path = FilePartUpload.get_qiniu_base_path callback_body[:file_size] = callback_body[:file_size].to_i meta = __get_meta_from_callback_body(callback_body[:mime], callback_body) - FilePartUpload::FileEntity.create!( - original: callback_body[:original], - token: callback_body[:token], - mime: callback_body[:mime], - meta: meta - ) + if defined? ::ActiveRecord::Base + FilePartUpload::FileEntity.create!( + original: callback_body[:original], + token: callback_body[:token], + mime: callback_body[:mime], + meta: meta.to_json + ) + else + FilePartUpload::FileEntity.create!( + original: callback_body[:original], + token: callback_body[:token], + mime: callback_body[:mime], + meta: meta + ) + end end diff --git a/app/models/concerns/file_part_upload/qiniu_methods.rb b/app/models/concerns/file_part_upload/qiniu_methods.rb index ad159df..5f02ff2 100755 --- a/app/models/concerns/file_part_upload/qiniu_methods.rb +++ b/app/models/concerns/file_part_upload/qiniu_methods.rb @@ -64,10 +64,6 @@ def seconds meta.try(:[], self.kind.to_s).try(:[], "total_duration").to_i end - def file_size - meta["file_size"] - end - def url(version = nil) base_url = File.join(FilePartUpload.get_qiniu_domain, token) @@ -116,11 +112,16 @@ def put_video_transcode_to_quene # 参考了 http://www.lecloud.com/ # 从七牛获取的 video_bit_rate 有时候是空,所以用 total_bit_rate 稳妥一些 - video_bit_rate = self.meta["video"]["total_bit_rate"].to_i - video_width = self.meta["video"]["width"].to_i - video_height = self.meta["video"]["height"].to_i + if defined? ::ActiveRecord::Base + json = meta_json + else + json = meta + end + video_bit_rate = json["video"]["total_bit_rate"].to_i + video_width = json["video"]["width"].to_i + video_height = json["video"]["height"].to_i - video_codec_name = self.meta["video"]["video_codec_name"] + video_codec_name = json["video"]["video_codec_name"] mulriple = VIDEO_BIT_RATE_MULRIPLES.select do |hash| !video_codec_name.match(hash[:video_codec_name]).blank? diff --git a/app/models/concerns/file_part_upload/qiniu_validate.rb b/app/models/concerns/file_part_upload/qiniu_validate.rb index b7e27cc..0dbb6be 100755 --- a/app/models/concerns/file_part_upload/qiniu_validate.rb +++ b/app/models/concerns/file_part_upload/qiniu_validate.rb @@ -1,18 +1,30 @@ module FilePartUpload module QiniuValidate - def self.included(base) - base.before_validation :set_kind_by_mime + extend ActiveSupport::Concern + included do + before_validation :set_kind_by_mime end def set_kind_by_mime + if defined? ::ActiveRecord::Base + if self.mime.present? + new_kind = FilePartUpload::Util.get_file_kind_by_mime_type(self.mime) + self.kind = new_kind if new_kind != self.kind + # 七牛的 mime 有时候有问题,比如 mpg 格式的视频,七牛会识别成 audio/mpeg + # 这个情况通过 meta 字段信息 fix + self.kind = "video" if !meta_json["video"].blank? && self.kind != "video" + self.kind = "audio" if !meta_json["audio"].blank? && self.kind != "audio" + end - if self.mime.present? - new_kind = FilePartUpload::Util.get_file_kind_by_mime_type(self.mime) - self.kind = new_kind if new_kind != self.kind - # 七牛的 mime 有时候有问题,比如 mpg 格式的视频,七牛会识别成 audio/mpeg - # 这个情况通过 meta 字段信息 fix - self.kind = "video" if !self.meta["video"].blank? && self.kind != "video" - self.kind = "audio" if !self.meta["audio"].blank? && self.kind != "audio" + else + if self.mime.present? + new_kind = FilePartUpload::Util.get_file_kind_by_mime_type(self.mime) + self.kind = new_kind if new_kind != self.kind + # 七牛的 mime 有时候有问题,比如 mpg 格式的视频,七牛会识别成 audio/mpeg + # 这个情况通过 meta 字段信息 fix + self.kind = "video" if !self.meta["video"].blank? && self.kind != "video" + self.kind = "audio" if !self.meta["audio"].blank? && self.kind != "audio" + end end end diff --git a/app/models/concerns/file_part_upload/transcoding_record_active_record.rb b/app/models/concerns/file_part_upload/transcoding_record_active_record.rb new file mode 100644 index 0000000..df18485 --- /dev/null +++ b/app/models/concerns/file_part_upload/transcoding_record_active_record.rb @@ -0,0 +1,71 @@ +module FilePartUpload + module TranscodingRecordActiveRecord + extend ActiveSupport::Concern + included do + extend Enumerize + + enumerize :status, in: [:processing, :success, :failure], default: :processing + + belongs_to :file_entity, class_name: 'FilePartUpload::FileEntity' + + before_create :send_to_qiniu_queue + before_save :put_pdf_transcode_to_quene + before_save :record_image_size_by_token_on_transcode_success + end + + def send_to_qiniu_queue + self.quniu_persistance_id = FilePartUpload::Util.put_to_qiniu_transcode_queue( + self.file_entity.token, + self.fops + ) + end + + def put_pdf_transcode_to_quene + return true if !self.file_entity.is_office? || self.name != "pdf" || !self.status.success? + + self.file_entity.update_page_count_by_pdf_url(self.url) + self.file_entity.put_pdf_transcode_to_quene_by_page_count + end + + def record_image_size_by_token_on_transcode_success + return true if (!self.file_entity.is_office? && !self.file_entity.is_pdf?) || self.name != "jpg" || !self.status.success? + + json_str = RestClient.get("#{self.url}?imageInfo").body + self.file_entity.meta["page_width"] = JSON.parse(json_str)["width"].to_i + self.file_entity.meta["page_height"] = JSON.parse(json_str)["height"].to_i + self.file_entity.save + end + + def url + File.join(FilePartUpload.get_qiniu_domain, [*token][0]) + end + + def urls + [*token].map do |t| + File.join(FilePartUpload.get_qiniu_domain, t) + end + end + + def refresh_status_form_qiniu + code = FilePartUpload::Util.get_qiniu_transcode_status(self.quniu_persistance_id) + update_status_by_code(code) + end + + def update_status_by_code(code) + # 状态码0成功,1等待处理,2正在处理,3处理失败,4通知提交失败。 + case code + when 0,4 + self.status = :success + when 1,2 + self.status = :processing + when 3 + self.status = :failure + end + + if self.changed.include?("status") + self.save + end + end + + end +end diff --git a/app/models/concerns/file_part_upload/transcoding_record_mongoid.rb b/app/models/concerns/file_part_upload/transcoding_record_mongoid.rb new file mode 100644 index 0000000..4f280ca --- /dev/null +++ b/app/models/concerns/file_part_upload/transcoding_record_mongoid.rb @@ -0,0 +1,79 @@ +module FilePartUpload + module TranscodingRecordMongoid + extend ActiveSupport::Concern + included do + include Mongoid::Document + include Mongoid::Timestamps + extend Enumerize + + field :name, type: String + field :fops, type: String + field :quniu_persistance_id, type: String + field :token + + enumerize :status, in: [:processing, :success, :failure], default: :processing + + belongs_to :file_entity + + before_create :send_to_qiniu_queue + before_save :put_pdf_transcode_to_quene + before_save :record_image_size_by_token_on_transcode_success + end + + def send_to_qiniu_queue + self.quniu_persistance_id = FilePartUpload::Util.put_to_qiniu_transcode_queue( + self.file_entity.token, + self.fops + ) + end + + def put_pdf_transcode_to_quene + return true if !self.file_entity.is_office? || self.name != "pdf" || !self.status.success? + + self.file_entity.update_page_count_by_pdf_url(self.url) + self.file_entity.put_pdf_transcode_to_quene_by_page_count + end + + def record_image_size_by_token_on_transcode_success + return true if (!self.file_entity.is_office? && !self.file_entity.is_pdf?) || self.name != "jpg" || !self.status.success? + + json_str = RestClient.get("#{self.url}?imageInfo").body + self.file_entity.meta["page_width"] = JSON.parse(json_str)["width"].to_i + self.file_entity.meta["page_height"] = JSON.parse(json_str)["height"].to_i + self.file_entity.save + end + + def url + File.join(FilePartUpload.get_qiniu_domain, [*token][0]) + end + + def urls + [*token].map do |t| + File.join(FilePartUpload.get_qiniu_domain, t) + end + end + + def refresh_status_form_qiniu + code = FilePartUpload::Util.get_qiniu_transcode_status(self.quniu_persistance_id) + update_status_by_code(code) + end + + def update_status_by_code(code) + # 状态码0成功,1等待处理,2正在处理,3处理失败,4通知提交失败。 + case code + when 0,4 + self.status = :success + when 1,2 + self.status = :processing + when 3 + self.status = :failure + end + + if self.changed.include?("status") + self.save + end + end + + + end +end diff --git a/app/models/file_part_upload/file_entity.rb b/app/models/file_part_upload/file_entity.rb index 9de3879..138a5ca 100755 --- a/app/models/file_part_upload/file_entity.rb +++ b/app/models/file_part_upload/file_entity.rb @@ -1,60 +1,13 @@ module FilePartUpload - class FileEntity - include Mongoid::Document - include Mongoid::Timestamps - extend Enumerize - - include FilePartUpload::QiniuValidate - include FilePartUpload::QiniuCreateMethods - include FilePartUpload::QiniuMethods - - # 原始文件名 - field :original, type: String - # content_type - field :mime, type: String - # image video office - # field :kind, type: String - KINDS = [:image, :audio, :video, :application, :text, :office, :pdf] - enumerize :kind, in: KINDS - - # 本地模式 时, 表示 保存的文件名 - # qiniu模式 时, 表示 文件在七牛 bucket 中保存的 token(path) - field :token, type: String - - # 保存文件的 meta 信息 - # 所有文件都会有 {"file_size" => 1000} - # 具体特定文件的 meta 信息格式待确定 - field :meta, type: Hash - - # 只用于 本地模式 - # 表示已经保存的文件片段的大小 - field :saved_size, type: Integer - - # 只用于 本地模式 - # 表示是否已经把文件片段合并 - field :merged, type: Boolean, default: false - - - validates :original, :presence => true - validates :file_size, :presence => true - validates :mime, :presence => true - validates :kind, :presence => true - - # 获取文件大小 - def file_size - self.meta["file_size"] - end - - def file_size=(file_size) - self.meta = {} if self.meta.blank? - self.meta["file_size"] = file_size.to_i + if defined? ::ActiveRecord::Base + class FileEntity < ActiveRecord::Base + include FilePartUpload::FileEntityActiveRecord end + end - KINDS.each do |kind_sym| - define_method "is_#{kind_sym}?" do - self.kind.to_s == kind_sym.to_s - end + if defined? ::Mongoid::Document + class FileEntity + include FilePartUpload::FileEntityMongoid end - end end diff --git a/app/models/file_part_upload/transcoding_record.rb b/app/models/file_part_upload/transcoding_record.rb index 976c1a9..fe422f4 100755 --- a/app/models/file_part_upload/transcoding_record.rb +++ b/app/models/file_part_upload/transcoding_record.rb @@ -1,75 +1,13 @@ module FilePartUpload - class TranscodingRecord - include Mongoid::Document - include Mongoid::Timestamps - extend Enumerize - - field :name, type: String - field :fops, type: String - field :quniu_persistance_id, type: String - field :token - - enumerize :status, in: [:processing, :success, :failure], default: :processing - - belongs_to :file_entity - - before_create :send_to_qiniu_queue - def send_to_qiniu_queue - self.quniu_persistance_id = FilePartUpload::Util.put_to_qiniu_transcode_queue( - self.file_entity.token, - self.fops - ) - end - - before_save :put_pdf_transcode_to_quene - def put_pdf_transcode_to_quene - return true if !self.file_entity.is_office? || self.name != "pdf" || !self.status.success? - - self.file_entity.update_page_count_by_pdf_url(self.url) - self.file_entity.put_pdf_transcode_to_quene_by_page_count - end - - before_save :record_image_size_by_token_on_transcode_success - def record_image_size_by_token_on_transcode_success - return true if (!self.file_entity.is_office? && !self.file_entity.is_pdf?) || self.name != "jpg" || !self.status.success? - - json_str = RestClient.get("#{self.url}?imageInfo").body - self.file_entity.meta["page_width"] = JSON.parse(json_str)["width"].to_i - self.file_entity.meta["page_height"] = JSON.parse(json_str)["height"].to_i - self.file_entity.save + if defined? ::ActiveRecord::Base + class TranscodingRecord < ActiveRecord::Base + include FilePartUpload::TranscodingRecordActiveRecord end + end - def url - File.join(FilePartUpload.get_qiniu_domain, [*token][0]) - end - - def urls - [*token].map do |t| - File.join(FilePartUpload.get_qiniu_domain, t) - end - end - - def refresh_status_form_qiniu - code = FilePartUpload::Util.get_qiniu_transcode_status(self.quniu_persistance_id) - update_status_by_code(code) - end - - def update_status_by_code(code) - # 状态码0成功,1等待处理,2正在处理,3处理失败,4通知提交失败。 - case code - when 0,4 - self.status = :success - when 1,2 - self.status = :processing - when 3 - self.status = :failure - end - - if self.changed.include?("status") - self.save - end + if defined? ::Mongoid::Document + class TranscodingRecord + include FilePartUpload::TranscodingRecordMongoid end - - end end diff --git a/lib/generators/active_record/file_part_upload_generator.rb b/lib/generators/active_record/file_part_upload_generator.rb new file mode 100644 index 0000000..f99077f --- /dev/null +++ b/lib/generators/active_record/file_part_upload_generator.rb @@ -0,0 +1,16 @@ +require 'rails/generators/active_record' +require 'active_support/core_ext' +require 'erb' + +module ActiveRecord + module Generators + class FilePartUploadGenerator < ActiveRecord::Generators::Base + source_root File.expand_path("../templates", __FILE__) + + def copy_initializer + migration_template "migration.rb", "db/migrate/create_file_part_upload.rb" + end + + end + end +end diff --git a/lib/generators/active_record/templates/migration.rb b/lib/generators/active_record/templates/migration.rb new file mode 100644 index 0000000..dd544cf --- /dev/null +++ b/lib/generators/active_record/templates/migration.rb @@ -0,0 +1,31 @@ +class CreateFilePartUpload < ActiveRecord::Migration + def change + create_table(:file_part_upload_file_entities) do |t| + t.string :original + t.string :mime + t.string :kind + t.string :token + t.string :meta + t.integer :saved_size + t.boolean :merged, default: false + + t.timestamps + end + + create_table(:file_part_upload_transcoding_records) do |t| + t.string :name + t.string :fops + t.string :quniu_persistance_id + t.string :token + t.string :status + t.string :meta + t.integer :saved_size + t.boolean :merged, default: false + t.integer :file_entity_id + + t.timestamps + end + + add_index(:file_part_upload_transcoding_records, :file_entity_id) + end +end diff --git a/pg_sample/.byebug_history b/pg_sample/.byebug_history new file mode 100644 index 0000000..55ef7a1 --- /dev/null +++ b/pg_sample/.byebug_history @@ -0,0 +1,27 @@ +q +@file_entity_video.kind +@file_entity_video +h["avinfo_audio_codec_name"] +h = JSON.parse @file_entity_video.meta +@file_entity_video.meta +@file_entity_video.is_audio? +@file_entity_video.is_audio +@file_entity_video +q +c +file_entity.file_size +c +file_entity.file_size +file_entity.meta +file_entity +c +file_entity.meta_json["file_size"] +file_entity.meta_json +meta_json["file_size"] +meta_json = JSON.parse file_entity.meta +meta_json = JSON.parse file_entity.meta.blank? +file_entity.meta.blank? +file_entity.meta +file_entity.file_size +file_entity.meta +file_entity diff --git a/pg_sample/.gitignore b/pg_sample/.gitignore new file mode 100644 index 0000000..5b61ab0 --- /dev/null +++ b/pg_sample/.gitignore @@ -0,0 +1,13 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all logfiles and tempfiles. +/log/* +!/log/.keep +/tmp diff --git a/pg_sample/Gemfile b/pg_sample/Gemfile new file mode 100644 index 0000000..1e0a88b --- /dev/null +++ b/pg_sample/Gemfile @@ -0,0 +1,56 @@ +source 'https://ruby.taobao.org' + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '4.2.3' +# Use SCSS for stylesheets +gem 'sass-rails', '~> 5.0' +# Use Uglifier as compressor for JavaScript assets +gem 'uglifier', '>= 1.3.0' +# Use CoffeeScript for .coffee assets and views +gem 'coffee-rails', '~> 4.1.0' +# See https://github.com/rails/execjs#readme for more supported runtimes +# gem 'therubyracer', platforms: :ruby + +# Use jquery as the JavaScript library +gem 'jquery-rails' +# Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks +gem 'turbolinks' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +gem 'jbuilder', '~> 2.0' +# bundle exec rake doc:rails generates the API under doc/api. +gem 'sdoc', '~> 0.4.0', group: :doc + +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +# Use Unicorn as the app server +# gem 'unicorn' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +# 更友好的出错页面 +group :test, :development do + gem 'better_errors' + gem 'binding_of_caller' + + gem 'byebug' + gem 'rspec-rails', '~> 3.0' +end + +group :development do + # Access an IRB console on exception pages or by using <%= console %> in views + gem 'web-console', '~> 2.0' +end + +group :test do + gem 'database_cleaner', '~> 1.4.1' + gem "factory_girl_rails" + gem 'capybara' +end + +# Use postgresql as the database for Active Record +gem 'pg' +gem 'haml' + +gem 'file-part-upload', path: '../' diff --git a/pg_sample/README.rdoc b/pg_sample/README.rdoc new file mode 100644 index 0000000..dd4e97e --- /dev/null +++ b/pg_sample/README.rdoc @@ -0,0 +1,28 @@ +== README + +This README would normally document whatever steps are necessary to get the +application up and running. + +Things you may want to cover: + +* Ruby version + +* System dependencies + +* Configuration + +* Database creation + +* Database initialization + +* How to run the test suite + +* Services (job queues, cache servers, search engines, etc.) + +* Deployment instructions + +* ... + + +Please feel free to use a different markup language if you do not plan to run +rake doc:app. diff --git a/pg_sample/Rakefile b/pg_sample/Rakefile new file mode 100644 index 0000000..ba6b733 --- /dev/null +++ b/pg_sample/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) + +Rails.application.load_tasks diff --git a/pg_sample/app/assets/images/.keep b/pg_sample/app/assets/images/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/app/assets/javascripts/application.js b/pg_sample/app/assets/javascripts/application.js new file mode 100644 index 0000000..e07c5a8 --- /dev/null +++ b/pg_sample/app/assets/javascripts/application.js @@ -0,0 +1,16 @@ +// This is a manifest file that'll be compiled into application.js, which will include all the files +// listed below. +// +// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, +// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. +// +// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the +// compiled file. +// +// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details +// about supported directives. +// +//= require jquery +//= require jquery_ujs +//= require turbolinks +//= require_tree . diff --git a/pg_sample/app/assets/stylesheets/application.css b/pg_sample/app/assets/stylesheets/application.css new file mode 100644 index 0000000..f9cd5b3 --- /dev/null +++ b/pg_sample/app/assets/stylesheets/application.css @@ -0,0 +1,15 @@ +/* + * This is a manifest file that'll be compiled into application.css, which will include all the files + * listed below. + * + * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, + * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. + * + * You're free to add application-wide styles to this file and they'll appear at the bottom of the + * compiled file so the styles you add here take precedence over styles defined in any styles + * defined in the other CSS/SCSS files in this directory. It is generally better to create a new + * file per style scope. + * + *= require_tree . + *= require_self + */ diff --git a/pg_sample/app/controllers/application_controller.rb b/pg_sample/app/controllers/application_controller.rb new file mode 100644 index 0000000..d83690e --- /dev/null +++ b/pg_sample/app/controllers/application_controller.rb @@ -0,0 +1,5 @@ +class ApplicationController < ActionController::Base + # Prevent CSRF attacks by raising an exception. + # For APIs, you may want to use :null_session instead. + protect_from_forgery with: :exception +end diff --git a/pg_sample/app/controllers/concerns/.keep b/pg_sample/app/controllers/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/app/helpers/application_helper.rb b/pg_sample/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/pg_sample/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/pg_sample/app/mailers/.keep b/pg_sample/app/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/app/models/.keep b/pg_sample/app/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/app/models/concerns/.keep b/pg_sample/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/app/views/layouts/application.html.erb b/pg_sample/app/views/layouts/application.html.erb new file mode 100644 index 0000000..8fa2b93 --- /dev/null +++ b/pg_sample/app/views/layouts/application.html.erb @@ -0,0 +1,14 @@ + + + + PgSample + <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> + <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + <%= csrf_meta_tags %> + + + +<%= yield %> + + + diff --git a/pg_sample/bin/bundle b/pg_sample/bin/bundle new file mode 100755 index 0000000..66e9889 --- /dev/null +++ b/pg_sample/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/pg_sample/bin/rails b/pg_sample/bin/rails new file mode 100755 index 0000000..5191e69 --- /dev/null +++ b/pg_sample/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/pg_sample/bin/rake b/pg_sample/bin/rake new file mode 100755 index 0000000..1724048 --- /dev/null +++ b/pg_sample/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/pg_sample/bin/setup b/pg_sample/bin/setup new file mode 100755 index 0000000..acdb2c1 --- /dev/null +++ b/pg_sample/bin/setup @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +Dir.chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file: + + puts "== Installing dependencies ==" + system "gem install bundler --conservative" + system "bundle check || bundle install" + + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # system "cp config/database.yml.sample config/database.yml" + # end + + puts "\n== Preparing database ==" + system "bin/rake db:setup" + + puts "\n== Removing old logs and tempfiles ==" + system "rm -f log/*" + system "rm -rf tmp/cache" + + puts "\n== Restarting application server ==" + system "touch tmp/restart.txt" +end diff --git a/pg_sample/config.ru b/pg_sample/config.ru new file mode 100644 index 0000000..bd83b25 --- /dev/null +++ b/pg_sample/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run Rails.application diff --git a/pg_sample/config/application.rb b/pg_sample/config/application.rb new file mode 100644 index 0000000..ea21f37 --- /dev/null +++ b/pg_sample/config/application.rb @@ -0,0 +1,29 @@ +require File.expand_path('../boot', __FILE__) + +require 'rails/all' + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module PgSample + class Application < Rails::Application + config.generators do |g| + g.factory_girl dir: 'spec/factories' + end + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # Do not swallow errors in after_commit/after_rollback callbacks. + config.active_record.raise_in_transactional_callbacks = true + end +end diff --git a/pg_sample/config/boot.rb b/pg_sample/config/boot.rb new file mode 100644 index 0000000..6b750f0 --- /dev/null +++ b/pg_sample/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/pg_sample/config/database.yml b/pg_sample/config/database.yml new file mode 100644 index 0000000..fa060b8 --- /dev/null +++ b/pg_sample/config/database.yml @@ -0,0 +1,85 @@ +# PostgreSQL. Versions 8.2 and up are supported. +# +# Install the pg driver: +# gem install pg +# On OS X with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On OS X with MacPorts: +# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem 'pg' +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see rails configuration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling + pool: 5 + +development: + <<: *default + database: pg_sample_development + + # The specified database role being used to connect to postgres. + # To create additional roles in postgres see `$ createuser --help`. + # When left blank, postgres will use the default role. This is + # the same name as the operating system user that initialized the database. + #username: pg_sample + + # The password associated with the postgres role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: pg_sample_test + +# As with config/secrets.yml, you never want to store sensitive information, +# like your database password, in your source code. If your source code is +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password as a unix environment variable when you boot +# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full rundown on how to provide these environment variables in a +# production deployment. +# +# On Heroku and other platform providers, you may have a full connection URL +# available as an environment variable. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# You can use this database configuration with: +# +# production: +# url: <%= ENV['DATABASE_URL'] %> +# +production: + <<: *default + database: pg_sample_production + username: pg_sample + password: <%= ENV['PG_SAMPLE_DATABASE_PASSWORD'] %> diff --git a/pg_sample/config/environment.rb b/pg_sample/config/environment.rb new file mode 100644 index 0000000..ee8d90d --- /dev/null +++ b/pg_sample/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require File.expand_path('../application', __FILE__) + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/pg_sample/config/environments/development.rb b/pg_sample/config/environments/development.rb new file mode 100644 index 0000000..b55e214 --- /dev/null +++ b/pg_sample/config/environments/development.rb @@ -0,0 +1,41 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + config.assets.debug = true + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # Adds additional error checking when serving assets at runtime. + # Checks for improperly declared sprockets dependencies. + # Raises helpful error messages. + config.assets.raise_runtime_errors = true + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/pg_sample/config/environments/production.rb b/pg_sample/config/environments/production.rb new file mode 100644 index 0000000..5c1b32e --- /dev/null +++ b/pg_sample/config/environments/production.rb @@ -0,0 +1,79 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Enable Rack::Cache to put a simple HTTP cache in front of your application + # Add `rack-cache` to your Gemfile before enabling this. + # For large-scale production use, consider using a caching reverse proxy like + # NGINX, varnish or squid. + # config.action_dispatch.rack_cache = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? + + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass + + # Do not fallback to assets pipeline if a precompiled asset is missed. + config.assets.compile = false + + # Asset digests allow you to set far-future HTTP expiration dates on all assets, + # yet still be able to expire them through the digest params. + config.assets.digest = true + + # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + # config.log_tags = [ :subdomain, :uuid ] + + # Use a different logger for distributed setups. + # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/pg_sample/config/environments/test.rb b/pg_sample/config/environments/test.rb new file mode 100644 index 0000000..1c19f08 --- /dev/null +++ b/pg_sample/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure static file server for tests with Cache-Control for performance. + config.serve_static_files = true + config.static_cache_control = 'public, max-age=3600' + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Randomize the order test cases are executed. + config.active_support.test_order = :random + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/pg_sample/config/initializers/assets.rb b/pg_sample/config/initializers/assets.rb new file mode 100644 index 0000000..01ef3e6 --- /dev/null +++ b/pg_sample/config/initializers/assets.rb @@ -0,0 +1,11 @@ +# Be sure to restart your server when you modify this file. + +# Version of your assets, change this if you want to expire all your assets. +Rails.application.config.assets.version = '1.0' + +# Add additional assets to the asset load path +# Rails.application.config.assets.paths << Emoji.images_path + +# Precompile additional assets. +# application.js, application.css, and all non-JS/CSS in app/assets folder are already added. +# Rails.application.config.assets.precompile += %w( search.js ) diff --git a/pg_sample/config/initializers/backtrace_silencers.rb b/pg_sample/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/pg_sample/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/pg_sample/config/initializers/cookies_serializer.rb b/pg_sample/config/initializers/cookies_serializer.rb new file mode 100644 index 0000000..7f70458 --- /dev/null +++ b/pg_sample/config/initializers/cookies_serializer.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.action_dispatch.cookies_serializer = :json diff --git a/pg_sample/config/initializers/filter_parameter_logging.rb b/pg_sample/config/initializers/filter_parameter_logging.rb new file mode 100644 index 0000000..4a994e1 --- /dev/null +++ b/pg_sample/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/pg_sample/config/initializers/inflections.rb b/pg_sample/config/initializers/inflections.rb new file mode 100644 index 0000000..ac033bf --- /dev/null +++ b/pg_sample/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/pg_sample/config/initializers/mime_types.rb b/pg_sample/config/initializers/mime_types.rb new file mode 100644 index 0000000..dc18996 --- /dev/null +++ b/pg_sample/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/pg_sample/config/initializers/session_store.rb b/pg_sample/config/initializers/session_store.rb new file mode 100644 index 0000000..622129a --- /dev/null +++ b/pg_sample/config/initializers/session_store.rb @@ -0,0 +1,3 @@ +# Be sure to restart your server when you modify this file. + +Rails.application.config.session_store :cookie_store, key: '_pg_sample_session' diff --git a/pg_sample/config/initializers/wrap_parameters.rb b/pg_sample/config/initializers/wrap_parameters.rb new file mode 100644 index 0000000..33725e9 --- /dev/null +++ b/pg_sample/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/pg_sample/config/locales/en.yml b/pg_sample/config/locales/en.yml new file mode 100644 index 0000000..0653957 --- /dev/null +++ b/pg_sample/config/locales/en.yml @@ -0,0 +1,23 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/pg_sample/config/routes.rb b/pg_sample/config/routes.rb new file mode 100644 index 0000000..8b35e34 --- /dev/null +++ b/pg_sample/config/routes.rb @@ -0,0 +1,58 @@ +Rails.application.routes.draw do + get '/upload_qiniu' => 'upload#qiniu' + mount FilePartUpload::Engine => '/file_part_upload', :as => 'file_part_upload' + # The priority is based upon order of creation: first created -> highest priority. + # See how all your routes lay out with "rake routes". + + # You can have the root of your site routed with "root" + # root 'welcome#index' + + # Example of regular route: + # get 'products/:id' => 'catalog#view' + + # Example of named route that can be invoked with purchase_url(id: product.id) + # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase + + # Example resource route (maps HTTP verbs to controller actions automatically): + # resources :products + + # Example resource route with options: + # resources :products do + # member do + # get 'short' + # post 'toggle' + # end + # + # collection do + # get 'sold' + # end + # end + + # Example resource route with sub-resources: + # resources :products do + # resources :comments, :sales + # resource :seller + # end + + # Example resource route with more complex sub-resources: + # resources :products do + # resources :comments + # resources :sales do + # get 'recent', on: :collection + # end + # end + + # Example resource route with concerns: + # concern :toggleable do + # post 'toggle' + # end + # resources :posts, concerns: :toggleable + # resources :photos, concerns: :toggleable + + # Example resource route within a namespace: + # namespace :admin do + # # Directs /admin/products/* to Admin::ProductsController + # # (app/controllers/admin/products_controller.rb) + # resources :products + # end +end diff --git a/pg_sample/config/secrets.yml b/pg_sample/config/secrets.yml new file mode 100644 index 0000000..09e511a --- /dev/null +++ b/pg_sample/config/secrets.yml @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rake secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: 3bf3ba137d39544d435bce57692a535ae7f655494a141c0b26e5fedf660d72037285e6ee670ecd387747d831b860ab198af009fabf92ee776c13c84a819fdc45 + +test: + secret_key_base: a10d05c036c8e28e1244faecf65a42a6cce6df5575b8980ac6842e15d5748fb580ed73dec3c00d1e8b5fd9064cdc2ab24c84689b362f13c9122d857540acfe4a + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/pg_sample/db/migrate/20160507045500_create_file_part_upload.rb b/pg_sample/db/migrate/20160507045500_create_file_part_upload.rb new file mode 100644 index 0000000..dd544cf --- /dev/null +++ b/pg_sample/db/migrate/20160507045500_create_file_part_upload.rb @@ -0,0 +1,31 @@ +class CreateFilePartUpload < ActiveRecord::Migration + def change + create_table(:file_part_upload_file_entities) do |t| + t.string :original + t.string :mime + t.string :kind + t.string :token + t.string :meta + t.integer :saved_size + t.boolean :merged, default: false + + t.timestamps + end + + create_table(:file_part_upload_transcoding_records) do |t| + t.string :name + t.string :fops + t.string :quniu_persistance_id + t.string :token + t.string :status + t.string :meta + t.integer :saved_size + t.boolean :merged, default: false + t.integer :file_entity_id + + t.timestamps + end + + add_index(:file_part_upload_transcoding_records, :file_entity_id) + end +end diff --git a/pg_sample/db/schema.rb b/pg_sample/db/schema.rb new file mode 100644 index 0000000..d92cd35 --- /dev/null +++ b/pg_sample/db/schema.rb @@ -0,0 +1,47 @@ +# encoding: UTF-8 +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20160507045500) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "file_part_upload_file_entities", force: :cascade do |t| + t.string "original" + t.string "mime" + t.string "kind" + t.string "token" + t.string "meta" + t.integer "saved_size" + t.boolean "merged", default: false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "file_part_upload_transcoding_records", force: :cascade do |t| + t.string "name" + t.string "fops" + t.string "quniu_persistance_id" + t.string "token" + t.string "status" + t.string "meta" + t.integer "saved_size" + t.boolean "merged", default: false + t.integer "file_entity_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "file_part_upload_transcoding_records", ["file_entity_id"], name: "index_file_part_upload_transcoding_records_on_file_entity_id", using: :btree + +end diff --git a/pg_sample/db/seeds.rb b/pg_sample/db/seeds.rb new file mode 100644 index 0000000..4edb1e8 --- /dev/null +++ b/pg_sample/db/seeds.rb @@ -0,0 +1,7 @@ +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup). +# +# Examples: +# +# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) +# Mayor.create(name: 'Emanuel', city: cities.first) diff --git a/pg_sample/lib/assets/.keep b/pg_sample/lib/assets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/lib/tasks/.keep b/pg_sample/lib/tasks/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/log/.keep b/pg_sample/log/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/public/404.html b/pg_sample/public/404.html new file mode 100644 index 0000000..b612547 --- /dev/null +++ b/pg_sample/public/404.html @@ -0,0 +1,67 @@ + + + + The page you were looking for doesn't exist (404) + + + + + + +
+
+

The page you were looking for doesn't exist.

+

You may have mistyped the address or the page may have moved.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/pg_sample/public/422.html b/pg_sample/public/422.html new file mode 100644 index 0000000..a21f82b --- /dev/null +++ b/pg_sample/public/422.html @@ -0,0 +1,67 @@ + + + + The change you wanted was rejected (422) + + + + + + +
+
+

The change you wanted was rejected.

+

Maybe you tried to change something you didn't have access to.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/pg_sample/public/500.html b/pg_sample/public/500.html new file mode 100644 index 0000000..061abc5 --- /dev/null +++ b/pg_sample/public/500.html @@ -0,0 +1,66 @@ + + + + We're sorry, but something went wrong (500) + + + + + + +
+
+

We're sorry, but something went wrong.

+
+

If you are the application owner check the logs for more information.

+
+ + diff --git a/pg_sample/public/favicon.ico b/pg_sample/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/public/robots.txt b/pg_sample/public/robots.txt new file mode 100644 index 0000000..3c9c7c0 --- /dev/null +++ b/pg_sample/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/pg_sample/spec/factories/file_part_uploads.rb b/pg_sample/spec/factories/file_part_uploads.rb new file mode 100644 index 0000000..23ff9e6 --- /dev/null +++ b/pg_sample/spec/factories/file_part_uploads.rb @@ -0,0 +1,9 @@ +FactoryGirl.define do + factory :image_file_entity, class: FilePartUpload::FileEntity do + original "1-120GQF34TY.jpg" + mime "image/jpeg" + kind "image" + token "/f/IuR0fINf.jpg" + meta "{\"file_size\":25067,\"image\":{\"rgba\":\"rgba(79,73,81,0)\",\"hex\":\"#4f4951\",\"height\":\"200\",\"width\":\"200\"}}" + end +end diff --git a/pg_sample/spec/features/.keep b/pg_sample/spec/features/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/spec/features/qiniu_spec.rb b/pg_sample/spec/features/qiniu_spec.rb new file mode 100755 index 0000000..d88ebc2 --- /dev/null +++ b/pg_sample/spec/features/qiniu_spec.rb @@ -0,0 +1,61 @@ +require 'rails_helper' + +describe 'upload http api', :type => :feature do + before{ + FilePartUpload.config do + mode :qiniu + + qiniu_bucket "fushang318" + qiniu_domain "http://qiniu_domain" + qiniu_base_path "f" + qiniu_app_access_key "access_key" + qiniu_app_secret_key "secret_key" + end + } + + it { + + visit "/file_part_upload/file_entities/uptoken" + json = JSON.parse(page.text) + expect(json["uptoken"].blank?).to eq(false) + + + @params = { "bucket"=>"fushang318", + "token"=>"/f/yscPYbwk.jpeg", + "file_size"=>"3514", + "image_rgb"=>"0xee4f60", + "original"=>"icon200x200.jpeg", + "mime" => "image/png", + "image_width"=>"200", + "image_height"=>"200", + "avinfo_format" => "", + "avinfo_total_bit_rate" => "", + "avinfo_total_duration" => "", + "avinfo_video_codec_name" => "", + "avinfo_video_bit_rate" => "", + "avinfo_video_duration" => "", + "avinfo_height" => "", + "avinfo_width" => "", + "avinfo_audio_codec_name" => "", + "avinfo_audio_bit_rate" => "", + "avinfo_audio_duration" => "" + } + + expect { + res = page.driver.post "/file_part_upload/file_entities", @params + json = JSON.parse(res.body) + + entity = FilePartUpload::FileEntity.find(json["file_entity_id"]) + + expect(entity.url).to eq("http://qiniu_domain/f/yscPYbwk.jpeg") + expect(entity.path).to eq("/f/yscPYbwk.jpeg") + expect(entity.file_size).to eq(3514) + expect(entity.original).to eq("icon200x200.jpeg") + expect(entity.mime).to eq("image/png") + expect(entity.kind).to eq("image") + expect(entity.token).to eq("/f/yscPYbwk.jpeg") + + }.to change {FilePartUpload::FileEntity.count}.by(1) + + } +end diff --git a/pg_sample/spec/models/add_methods_spec.rb b/pg_sample/spec/models/add_methods_spec.rb new file mode 100755 index 0000000..93c1256 --- /dev/null +++ b/pg_sample/spec/models/add_methods_spec.rb @@ -0,0 +1,24 @@ +require 'rails_helper' + +describe FilePartUpload do + before{ + module ExpandMethods + def ttt + "ttt" + end + end + FilePartUpload.config do + add_methods ExpandMethods + end + + file_name = "image.jpg" + data_path = File.expand_path("../data",__FILE__) + image_path = File.join(data_path, file_name) + file = File.new(image_path) + @entity = FilePartUpload::FileEntity.create(:original => file_name, :file_size => file.size) + } + + it{ + expect(@entity.ttt).to eq("ttt") + } +end diff --git a/pg_sample/spec/models/data/1/image b/pg_sample/spec/models/data/1/image new file mode 100755 index 0000000..dce9d74 Binary files /dev/null and b/pg_sample/spec/models/data/1/image differ diff --git a/pg_sample/spec/models/data/2/image_split_aa b/pg_sample/spec/models/data/2/image_split_aa new file mode 100644 index 0000000..1d16c3e Binary files /dev/null and b/pg_sample/spec/models/data/2/image_split_aa differ diff --git a/pg_sample/spec/models/data/2/image_split_ab b/pg_sample/spec/models/data/2/image_split_ab new file mode 100644 index 0000000..16b3f3b Binary files /dev/null and b/pg_sample/spec/models/data/2/image_split_ab differ diff --git a/pg_sample/spec/models/data/3/image_split_aa b/pg_sample/spec/models/data/3/image_split_aa new file mode 100644 index 0000000..a344f13 Binary files /dev/null and b/pg_sample/spec/models/data/3/image_split_aa differ diff --git a/pg_sample/spec/models/data/3/image_split_ab b/pg_sample/spec/models/data/3/image_split_ab new file mode 100644 index 0000000..af74c20 Binary files /dev/null and b/pg_sample/spec/models/data/3/image_split_ab differ diff --git a/pg_sample/spec/models/data/3/image_split_ac b/pg_sample/spec/models/data/3/image_split_ac new file mode 100644 index 0000000..582e4af Binary files /dev/null and b/pg_sample/spec/models/data/3/image_split_ac differ diff --git a/pg_sample/spec/models/data/image.jpg b/pg_sample/spec/models/data/image.jpg new file mode 100755 index 0000000..dce9d74 Binary files /dev/null and b/pg_sample/spec/models/data/image.jpg differ diff --git a/pg_sample/spec/models/data/text.doc b/pg_sample/spec/models/data/text.doc new file mode 100755 index 0000000..56a6051 --- /dev/null +++ b/pg_sample/spec/models/data/text.doc @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/pg_sample/spec/models/data/text.txt b/pg_sample/spec/models/data/text.txt new file mode 100755 index 0000000..f3a3485 --- /dev/null +++ b/pg_sample/spec/models/data/text.txt @@ -0,0 +1 @@ +text \ No newline at end of file diff --git a/pg_sample/spec/models/qiniu_audio_and_video_transcode_spec.rb b/pg_sample/spec/models/qiniu_audio_and_video_transcode_spec.rb new file mode 100755 index 0000000..0049f2a --- /dev/null +++ b/pg_sample/spec/models/qiniu_audio_and_video_transcode_spec.rb @@ -0,0 +1,138 @@ +require 'rails_helper' + +describe 'qiniu_audio_and_video_transcode' do + before{ + module FilePartUpload + class Util + + def self.put_to_qiniu_transcode_queue(origin_key, fops) + return "#{origin_key}_#{fops}_fops" + end + + def self.get_qiniu_transcode_status(persistance_id) + return 0 + end + + end + end + + + FilePartUpload.config do + mode :qiniu + + qiniu_bucket "fushang318" + qiniu_domain "http://qiniu_domain" + qiniu_base_path "f" + qiniu_audio_and_video_transcode :enable + end + + callback_body_video = { + bucket: "fushang318", + token: "f/aQK4F8rt.mp4", + file_size: "912220", + image_rgb: "", + original: "腾讯网迷你版 2015_9_29 16_11_59.mp4", + mime: "video/mp4", + image_width: "", + image_height: "", + avinfo_format: "mov,mp4,m4a,3gp,3g2,mj2", + avinfo_total_bit_rate: "1791016", + avinfo_total_duration: "4.074646", + avinfo_video_codec_name: "h264", + avinfo_video_bit_rate: "1650102", + avinfo_video_duration: "4.070733", + avinfo_height: "552", + avinfo_width: "768", + avinfo_audio_codec_name: "aac", + avinfo_audio_bit_rate: "131534", + avinfo_audio_duration: "4.074667" + } + + callback_body_audio = { + bucket: "fushang318", + token: "f/G8UB1myy.mp3", + file_size: "18392", + image_rgb: "", + original: "car-engine-loop-493679_SOUNDDOGS__au.mp3", + mime: "audio/mp3", + image_width: "", + image_height: "", + avinfo_format: "mp3", + avinfo_total_bit_rate: "34771", + avinfo_total_duration: "4.231500", + avinfo_video_codec_name: "", + avinfo_video_bit_rate: "", + avinfo_video_duration: "", + avinfo_height: "", + avinfo_width: "", + avinfo_audio_codec_name: "mp3", + avinfo_audio_bit_rate: "32000", + avinfo_audio_duration: "4.231500" + } + + + callback_body = { + bucket: "fushang318", + token: "/f/IuR0fINf.jpg", + file_size: "25067", + original: "1-120GQF34TY.jpg", + mime: "image/jpeg", + image_width: "200", + image_height: "200", + image_rgb: "0x4f4951" + } + + @file_entity_video = FilePartUpload::FileEntity.from_qiniu_callback_body(callback_body_video) + @file_entity_audio = FilePartUpload::FileEntity.from_qiniu_callback_body(callback_body_audio) + @file_entity = FilePartUpload::FileEntity.from_qiniu_callback_body(callback_body) + } + + it{ + expect(FilePartUpload.get_qiniu_audio_and_video_transcode).to eq("enable") + } + + it{ + expect(@file_entity_video.valid?).to eq(true) + + expect(@file_entity_video.is_audio?).to eq(false) + expect(@file_entity_video.is_video?).to eq(true) + + expect(@file_entity_video.transcode_info).to eq({"标清"=>"processing"}) + expect(@file_entity_video.transcode_success?).to eq(false) + + @file_entity_video.transcoding_records.each do |tr| + tr.refresh_status_form_qiniu + end + + expect(@file_entity_video.transcode_info).to eq({"标清"=>"success"}) + expect(@file_entity_video.transcode_success?).to eq(true) + } + + it{ + expect(@file_entity_audio.valid?).to eq(true) + + expect(@file_entity_audio.is_audio?).to eq(true) + expect(@file_entity_audio.is_video?).to eq(false) + + expect(@file_entity_audio.transcode_info).to eq({"default"=>"processing"}) + expect(@file_entity_audio.transcode_success?).to eq(false) + + @file_entity_audio.transcoding_records.each do |tr| + tr.refresh_status_form_qiniu + end + + expect(@file_entity_audio.transcode_info).to eq({"default"=>"success"}) + expect(@file_entity_audio.transcode_success?).to eq(true) + } + + it{ + expect(@file_entity.valid?).to eq(true) + + expect(@file_entity.is_audio?).to eq(false) + expect(@file_entity.is_video?).to eq(false) + expect(@file_entity.transcode_info).to eq({}) + + expect(@file_entity.transcoding_records.count).to eq(0) + } + +end diff --git a/pg_sample/spec/models/qiniu_pfop_pipeline_spec.rb b/pg_sample/spec/models/qiniu_pfop_pipeline_spec.rb new file mode 100755 index 0000000..bbe54f0 --- /dev/null +++ b/pg_sample/spec/models/qiniu_pfop_pipeline_spec.rb @@ -0,0 +1,20 @@ +require 'rails_helper' + +describe 'get_qiniu_pfop_pipeline' do + it{ + expect(FilePartUpload.get_qiniu_pfop_pipeline).to eq(nil) + + FilePartUpload.config do + mode :qiniu + + qiniu_bucket "fushang318" + qiniu_domain "http://qiniu_domain" + qiniu_base_path "f" + qiniu_audio_and_video_transcode :enable + qiniu_pfop_pipeline "hahaha" + end + + expect(FilePartUpload.get_qiniu_pfop_pipeline).to eq("hahaha") + } + +end diff --git a/pg_sample/spec/models/qiniu_spec.rb b/pg_sample/spec/models/qiniu_spec.rb new file mode 100755 index 0000000..9bd4af9 --- /dev/null +++ b/pg_sample/spec/models/qiniu_spec.rb @@ -0,0 +1,70 @@ +require 'rails_helper' + +describe 'qiniu mode' do + before{ + FilePartUpload.config do + mode :qiniu + + qiniu_bucket "fushang318" + qiniu_domain "http://qiniu_domain" + qiniu_base_path "f" + + image_version :large do + process :resize_to_fill => [180, 180] + end + image_version :normal do + process :resize_to_fill => [64, 63] + end + image_version :small do + process :resize_to_fill => [30, 32] + end + + image_version :xxx do + process :resize_to_fit => [30, 31] + end + end + + callback_body = { + bucket: "fushang318", + token: "/f/IuR0fINf.jpg", + file_size: "25067", + original: "1-120GQF34TY.jpg", + mime: "image/jpeg", + image_width: "200", + image_height: "200", + image_rgb: "0x4f4951" + } + + @file_entity = FilePartUpload::FileEntity.from_qiniu_callback_body(callback_body) + } + + it{ + image_versions = FilePartUpload.file_part_upload_config[:qiniu_image_versions] + image_versions.should == { + "large" => {:type=>"resize_to_fill", :args=>[180, 180]}, + "normal" => {:type=>"resize_to_fill", :args=>[64, 63]}, + "small" => {:type=>"resize_to_fill", :args=>[30, 32]}, + "xxx" => {:type=>"resize_to_fit", :args=>[30, 31]} + } + } + + it{ + base_url = File.join(FilePartUpload.get_qiniu_domain, FilePartUpload.get_qiniu_base_path, 'IuR0fINf.jpg') + expect(@file_entity.url(:large)).to eq("#{base_url}?imageMogr2/thumbnail/!180x180r/gravity/Center/crop/180x180") + expect(@file_entity.url(:normal)).to eq("#{base_url}?imageMogr2/thumbnail/!64x63r/gravity/Center/crop/64x63") + expect(@file_entity.url(:xxx)).to eq("#{base_url}?imageMogr2/thumbnail/30x31") + } + + it{ + expect(@file_entity.original).to eq("1-120GQF34TY.jpg") + expect(@file_entity.url).to eq(File.join(FilePartUpload.get_qiniu_domain, FilePartUpload.get_qiniu_base_path, 'IuR0fINf.jpg')) + expect(@file_entity.kind.image?).to eq(true) + } + + it{ + file_entity = FilePartUpload::FileEntity.find(@file_entity.id) + expect(file_entity.file_size).to eq(25067) + } + + +end diff --git a/pg_sample/spec/rails_helper.rb b/pg_sample/spec/rails_helper.rb new file mode 100644 index 0000000..3d34256 --- /dev/null +++ b/pg_sample/spec/rails_helper.rb @@ -0,0 +1,41 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../../config/environment', __FILE__) +# Prevent database truncation if the environment is production +abort("The Rails environment is running in production mode!") if Rails.env.production? +require 'spec_helper' +require 'rspec/rails' +# Add additional requires below this line. Rails is not loaded until this point! + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f } + +RSpec.configure do |config| + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, :type => :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://relishapp.com/rspec/rspec-rails/docs + config.infer_spec_type_from_file_location! + +end diff --git a/pg_sample/spec/spec_helper.rb b/pg_sample/spec/spec_helper.rb new file mode 100644 index 0000000..05d5321 --- /dev/null +++ b/pg_sample/spec/spec_helper.rb @@ -0,0 +1,96 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# The `.rspec` file also contains a few flags that are not defaults but that +# users commonly want. +# +# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + config.expect_with :rspec do |c| + c.syntax = [:should, :expect] + end + + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # These two settings work together to allow you to limit a spec run + # to individual examples or groups you care about by tagging them with + # `:focus` metadata. When nothing is tagged with `:focus`, all examples + # get run. + config.filter_run :focus + config.run_all_when_everything_filtered = true + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # - http://myronmars.to/n/dev-blog/2012/06/rspecs-new-expectation-syntax + # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/ + # - http://myronmars.to/n/dev-blog/2014/05/notable-changes-in-rspec-3#new__config_option_to_disable_rspeccore_monkey_patching + config.disable_monkey_patching! + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = 'doc' + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/pg_sample/spec/support/capybara.rb b/pg_sample/spec/support/capybara.rb new file mode 100755 index 0000000..370d15f --- /dev/null +++ b/pg_sample/spec/support/capybara.rb @@ -0,0 +1 @@ +require 'capybara/rails' diff --git a/pg_sample/spec/support/factory_girl.rb b/pg_sample/spec/support/factory_girl.rb new file mode 100755 index 0000000..5d1c087 --- /dev/null +++ b/pg_sample/spec/support/factory_girl.rb @@ -0,0 +1,18 @@ +require 'database_cleaner' +RSpec.configure do |config| + config.include FactoryGirl::Syntax::Methods + + config.before(:each) do + begin + DatabaseCleaner.start + FactoryGirl.lint + ensure + DatabaseCleaner.clean + end + end + + config.before(:suite) do + DatabaseCleaner.strategy = :truncation + DatabaseCleaner.clean_with(:truncation) + end +end \ No newline at end of file diff --git a/pg_sample/test/controllers/.keep b/pg_sample/test/controllers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/test/fixtures/.keep b/pg_sample/test/fixtures/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/test/helpers/.keep b/pg_sample/test/helpers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/test/integration/.keep b/pg_sample/test/integration/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/test/mailers/.keep b/pg_sample/test/mailers/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/test/models/.keep b/pg_sample/test/models/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/test/test_helper.rb b/pg_sample/test/test_helper.rb new file mode 100644 index 0000000..92e39b2 --- /dev/null +++ b/pg_sample/test/test_helper.rb @@ -0,0 +1,10 @@ +ENV['RAILS_ENV'] ||= 'test' +require File.expand_path('../../config/environment', __FILE__) +require 'rails/test_help' + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + + # Add more helper methods to be used by all tests here... +end diff --git a/pg_sample/vendor/assets/javascripts/.keep b/pg_sample/vendor/assets/javascripts/.keep new file mode 100644 index 0000000..e69de29 diff --git a/pg_sample/vendor/assets/stylesheets/.keep b/pg_sample/vendor/assets/stylesheets/.keep new file mode 100644 index 0000000..e69de29 diff --git a/qiniu_sample/Gemfile b/qiniu_sample/Gemfile index 6e3f345..6facba1 100755 --- a/qiniu_sample/Gemfile +++ b/qiniu_sample/Gemfile @@ -30,15 +30,11 @@ gem 'sdoc', '~> 0.4.0', group: :doc # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +gem 'web-console', group: :development + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' - - # Access an IRB console on exception pages or by using <%= console %> in views - gem 'web-console', '~> 2.0' - - # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring - gem 'spring' end diff --git a/sample/Gemfile b/sample/Gemfile index c8689c5..fe255c4 100755 --- a/sample/Gemfile +++ b/sample/Gemfile @@ -10,16 +10,12 @@ gem 'turbolinks' gem 'jbuilder', '~> 2.0' gem 'sdoc', '~> 0.4.0', group: :doc +gem 'web-console', group: :development + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' - # Access an IRB console on exception pages or by using <%= console %> in views - gem 'web-console', '~> 2.0' - - # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring - gem 'spring' - gem 'rspec-rails', '~> 3.0' end