Class: SourceCode
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- SourceCode
- Includes:
- RubyToBlock
- Defined in:
- app/models/source_code.rb
Overview
ソースコードを表現するモデル
Constant Summary collapse
- MAX_REMIX_COUNT =
1000
Class Method Summary collapse
-
.make_remix_filename(home_dir, filename) ⇒ Object
リミックス用のファイル名を生成する.
Instance Method Summary collapse
-
#check_syntax ⇒ Object
シンタックスをチェックする.
-
#digest ⇒ Object
ハッシュ値を計算する.
-
#include_block?(type) ⇒ Boolean
指定した命令ブロックを含んでいるかどうかを返す.
-
#run(path) ⇒ Object
プログラムを実行する.
-
#summary ⇒ Object
ソースコードの概要を取得する.
-
#xml? ⇒ Boolean
ソースコードの種別がXML形式かどうかを返す.
Methods included from RubyToBlock
Class Method Details
.make_remix_filename(home_dir, filename) ⇒ Object
リミックス用のファイル名を生成する
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'app/models/source_code.rb', line 23 def self.make_remix_filename(home_dir, filename) home_dir = Pathname(home_dir). filename = filename.dup ext = filename.slice!(/\.rb(\.xml)?$/) filename.slice!(/(_remix(\d+)?)+$/) basename = "#{filename}_remix" MAX_REMIX_COUNT.times do |i| suffix = (i == 0 ? '' : sprintf('%02d', i + 1)) remix_name = "#{basename}#{suffix}" if !home_dir.join("#{remix_name}.rb").exist? && !home_dir.join("#{remix_name}.rb.xml").exist? return "#{remix_name}#{ext}" end end fail "reach max remix count...: #{filename}" end |
Instance Method Details
#check_syntax ⇒ Object
シンタックスをチェックする
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'app/models/source_code.rb', line 41 def check_syntax _, stderr_str, status = *open3_capture3_ruby_c return [] if status.success? stderr_str.lines.each.with_object([]) { |line, res| if (md = /^.*:(\d+): (.*)$/.match(line)) res << { row: md[1].to_i, column: 0, message: md[2] } elsif (md = /( +)\^$/.match(line)) res[-1][:column] = md[1].length end } end |
#digest ⇒ Object
ハッシュ値を計算する
63 64 65 |
# File 'app/models/source_code.rb', line 63 def digest Digest::SHA256.hexdigest(data) end |
#include_block?(type) ⇒ Boolean
指定した命令ブロックを含んでいるかどうかを返す
91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'app/models/source_code.rb', line 91 def include_block?(type) if xml? doc = Nokogiri::HTML.parse(data) if type.is_a?(Regexp) doc.xpath(%(//block[matches(@type, '#{type.source}')]), MatchesXPathFunction.new).length > 0 else doc.xpath(%(//block[@type="#{type}"])).length > 0 end else false end end |
#run(path) ⇒ Object
プログラムを実行する
55 56 57 58 59 60 |
# File 'app/models/source_code.rb', line 55 def run(path) _, stderr_str, status = *open3_capture3_run_program(path) return [] if status.success? (stderr_str) end |
#summary ⇒ Object
ソースコードの概要を取得する
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'app/models/source_code.rb', line 68 def summary res = {} if xml? res[:filename] = filename.sub(/\.xml\z/, '') doc = Nokogiri::HTML.parse(data) if (attr = doc.xpath('//character[1]/@costumes').first) res[:imageUrl] = "/smalruby/assets/#{attr.value}" end text = doc.xpath('//block[@type="ruby_comment"][1]' + '/field[@name="COMMENT"]/text()').first res[:title] = text.to_s if text else res[:filename] = filename end res[:title] = res[:filename] unless res[:title] res end |
#xml? ⇒ Boolean
ソースコードの種別がXML形式かどうかを返す
106 107 108 |
# File 'app/models/source_code.rb', line 106 def xml? !!(/\.xml\z/ =~ filename) end |