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