# -*- coding: utf-8 -*- require 'rubygems' require 'sinatra' require 'sass' require 'haml' require 'i18n' if ENV['MILKODE_SINATRA_RELOADER'] require 'sinatra/reloader' also_reload '../../**/*.rb' end $LOAD_PATH.unshift '../..' require 'milkode/common/util' require 'milkode/cdweb/lib/database' require 'milkode/cdweb/lib/command' require 'milkode/cdweb/lib/mkurl' require 'milkode/cdweb/lib/web_setting' require 'milkode/cdweb/lib/package_list' require 'milkode/cdweb/lib/info_home' require 'milkode/cdweb/lib/info_package' require 'sinatra/url_for' I18n.load_path += Dir[File.join(File.dirname(__FILE__), 'locales', '*.yml').to_s] set :haml, :format => :html5 enable :sessions get '/js/:filename' do content_type :js erb(File.read(File.join(settings.views, params[:filename]))) end get '/css/milkode.css' do content_type :css contents = File.read(File.join(settings.views, 'milkode.scss')) contents = erb(contents) engine = Sass::Engine.new(contents, :syntax => :scss) engine.render end get '/' do if Database.validate? @setting = WebSetting.new @version = Milkode::VERSION @package_num = Database.instance.yaml_package_num @file_num = Database.instance.totalRecords @package_list = PackageList.new(Database.instance.grndb, url_for('')) haml :index, :layout => false else <<EOF <h1>Setup Error!</h1> Database Directory: #{Database.dbdir}<br> EOF end end def package_path(homeurl, path) homeurl + path.sub(homeurl, "").split('/')[0,2].join('/') end post '/search*' do path = unescape(params[:pathname]) if params[:clear] redirect Mkurl.new("#{path}", params).inherit_shead else homeurl = url_for "/home" case params[:shead] when 'all' path = homeurl when 'package' path = package_path(homeurl, path) when 'directory' # do nothing else path = package_path(homeurl, path) end query = Query.new(params[:query]) # gotolineモードで1つだけ渡された時は直接ジャンプ if query.keywords.size == 1 && Milkode::Util.gotoline_keyword?(query.keywords[0]) gotoline = Milkode::Util.parse_gotoline(query.keywords)[0] path2 = File.join(url_for('/home'), gotoline[0][0]) redirect Mkurl.new(path2, params).inherit_query_shead + "#n#{gotoline[1]}" else redirect Mkurl.new("#{path}", params).inherit_query_shead end end end post '/command' do case params[:kind] when 'update' before = Time.now if (params[:name] == '') result = Database.instance.update_all update_result_str(result, before) else result = Database.instance.update(params[:name]) update_result_str(result, before) end when 'favorite' Database.instance.set_fav(params[:name], params[:favorited] == 'true') @package_list = PackageList.new(Database.instance.grndb, url_for('')) t(:favorite) + ": " + @package_list.favorite_list({}) end end get '/home*' do |path| before = Time.now path = path.sub(/^\//, "") record = Database.instance.record(path) @package_list = PackageList.new(Database.instance.grndb, url_for('')) suburl = url_for('') update_locale if path.empty? if (params[:query] and !params[:query].empty?) search(path, params, before, suburl, @locale) else packages(params, before, suburl, @locale) end elsif (record) view(record, params, before) else if (params[:query] and !params[:query].empty?) search(path, params, before, suburl, @locale) else filelist(path, params, before, suburl) end end end get %r{/help} do @setting = WebSetting.new @path = "" update_locale haml :help end get '/info' do obj = InfoHome.new(url_for '') @setting = WebSetting.new @path = "" @summary_content = obj.summary_content @record_content = obj.record_content haml :info_home end get '/info/:package' do before = Time.now name = params[:package] obj = InfoPackage.new(name, url_for('')) @setting = WebSetting.new @path = name @summary_content = obj.summary_content @plang_content = obj.plang_content @elapsed = Time.now - before haml :info_package end get '/gomilk' do if ENV['MILKODE_SUPPORT_GOMILK'] search_for_gomilk(params) else "Error: Need 'milk web --gomilk'" end end # -- helper function -- helpers do # -- escape functions -- alias h escape_html alias escape_url escape def escape_path(src) escape_url(src).gsub("%2F", '/') end # -- utility -- def link(query, text = nil) if text.nil? "<a href='#{'/home?query=' + escape_url(query)}'>#{query}</a>" else "<a href='#{'/home?query=' + escape_url(query)}'>#{text}</a>" end end def create_select_shead(value) value ||= "package" data = [ ['all' , t(:all) ], ['package' , t(:package) ], ['directory', t(:directory)], ] <<EOF <select name="shead" id="shead"> #{data.map{|v| "<option value='#{v[0]}' #{v[0] == value ? 'selected' : ''}>#{v[1]}</option>"}.join} </select> EOF end def create_select_package(path) value = package_name(path) value = '---' if value == "root" data = ['---'] + Database.instance.packages(nil) <<EOF <select name="package" id="package" onchange="select_package()"> #{data.map{|v| "<option value='#{v}' #{v == value ? 'selected' : ''}>#{v}</option>"}.join} </select> EOF end def create_select_package_home value = '---' data = ['---'] + Database.instance.packages(nil) <<EOF <select name="package" id="package_home" onchange="select_package_home()"> #{data.map{|v| "<option value='#{v}' #{v == value ? 'selected' : ''}>#{v}</option>"}.join} </select> EOF end def create_checkbox(name, value, label) str = (value) ? 'checked' : '' "<label class='checkbox inline'><input type='checkbox' name='#{name}' value='on' #{str}/>#{label}</label>" end def create_headmenu(path, query, flistpath = '') suburl = url_for "" href = Mkurl.new("#{suburl}/home/#{path}", params).inherit_query_shead flist = File.join("#{suburl}/home/#{path}", flistpath) package_name = "" modal_body = t(:update_all) if (path != "") package_name = path.split('/')[0] update_locale modal_body = I18n.t(:update_package, {package_name: package_name, locale: @locale}) end info_path = "#{suburl}/info" info_path = File.join(info_path, package_name) if package_name != "" update_menu = "#{headicon('view-refresh-4.png', suburl)}<a href='#updateModal' class='headmenu' data-toggle='modal'>#{t(:update_packages)}</a> " update_menu = "" if @setting.hide_update_button <<EOF #{headicon('go-home-5.png', suburl)}<a href="#{suburl}/home" class="headmenu">#{t(:home)}</a> #{headicon('directory.png', suburl)}<a href="#{flist}" class="headmenu">#{t(:directory)}</a> #{update_menu} #{headicon('info.png', suburl)}<a href="#{info_path}" class="headmenu">#{t(:stats)}</a> #{headicon('help.png', suburl)}<a href="#{suburl}/help" class="headmenu">#{t(:help)}</a> <div id="updateModal" class="modal hide fade"> <div class="modal-header"> <a href="#" class="close" data-dismiss="modal">×</a> <h3>#{t(:update_packages)}</h3> </div> <div class="modal-body"> <h4>#{modal_body}</h4> </div> <div class="modal-footer"> <a href="#" id="updateCancel" class="btn" data-dismiss="modal">Cancel</a> <a href="#" id="updateOk" class="btn btn-primary" data-loading-text="Updating..." milkode-package-name="#{package_name}">OK</a> </div> </div> <div id="lineno-modal" class="modal hide"> <div class="modal-header"> <a href="#" class="close" data-dismiss="modal">×</a> <h3 id="lineno-path"></h3> </div> <div class="modal-body"> <table class="CodeRay"><tr> <td class="code"><pre id="lineno-body"> </pre></td> </tr></table> </div> <div class="modal-footer"> <span id="lineno-copyall"></span> <a href="#" id="lineno-ok" class="btn" data-dismiss="modal">OK</a> </div> </div> EOF end def create_favorite_list(package_list) <<EOF <div class="favorite_list"> #{t(:favorite)}: #{package_list.favorite_list(params)} </div> </div> EOF end def headicon(name, suburl) "<img alt='' style='vertical-align:center; border: 0px; margin: 0px;' src='#{suburl}/images/#{name}'>" end def topic_path(path, params) href = '' path = File.join('home', path) path.split('/').map_with_index {|v, index| href += '/' + v "<a id='topic_#{index}' href='#{url_for Mkurl.new(href, params).inherit_query_shead}' onclick='topic_path(\"topic_#{index}\");'>#{v}</a>" }.join('/') end HASH = { '.h' => ['.c', '.cpp', '.m', '.mm'], '.c' => ['.h'], '.hpp' => ['.cpp'], '.cpp' => ['.hpp', '.h'], '.m' => ['.h'], '.mm' => ['.h'], } def additional_info(path, parms) suffix = File.extname path cadet = HASH[suffix] if (cadet) result = cadet.find do |v| Database.instance.record(path.gsub(/#{suffix}\Z/, v)) end if (result) path2 = path.gsub(/#{suffix}\Z/, result) " (<a href='#{url_for Mkurl.new(File.join('/home', path2), params).inherit_query_shead}'>#{result}</a>) " else '' end else '' end end def package_name(path) (path == "") ? 'root' : path.split('/')[0] end def current_name(path) (path == "") ? 'root' : File.basename(path) end def path_title(path) (path == "") ? "root" : path end def filelist_title(path) (path == "") ? "Package List" : path end def update_result_str(result, before) r = [] r << "#{result.package_count} packages" if result.package_count > 1 r << "#{result.file_count} records" r << "#{result.add_count} add" r << "#{result.update_count} update" "#{r.join(', ')} (#{Time.now - before} sec)" end def favstar(path) pname = package_name(path) if pname != "root" classes = Database.instance.fav?(pname) ? "star favorited" : "star" "<a href=\"javascript:\" class=\"#{classes}\" milkode-package-name=\"#{pname}\">Favorite Me</a>" else "" end end def goto_github_project(path) return "" if (path == "") paths = path.split('/') package = Database.instance.yaml_package(paths[0]) return "" unless package.options[:github] image_href = 'https://raw.github.com/github/media/master/octocats/blacktocat-16.png' url = "https://github.com/#{package.options[:github]}" if (paths.size == 1) "<a href='#{url}' target=\"_blank\"><img src='#{image_href}'></img></a>" else "<a href='#{url}/tree/master/#{paths[1..-1].join('/')}' target=\"_blank\"><img src='#{image_href}'></img></a>" end end # .search-summary に追加情報を表示したい時はこの関数をオーバーライド def search_summary_hook(path) goto_github_project(path) end ## for I18N def ua_locale # Pulls the browser's language @env["HTTP_ACCEPT_LANGUAGE"][0,2] end def update_locale unless @locale begin # Support session @locale = params[:locale] || session[:locale] || ua_locale || 'en' session[:locale] = @locale rescue NameError # 'session' variable can't find during testing @locale = 'en' end # Reload with sinatra-reloader I18n.reload! if ENV['MILKODE_SINATRA_RELOADER'] end end def t(*args) update_locale I18n.t(*args, locale: @locale) end end class Array def map_with_index! each_with_index do |e, idx| self[idx] = yield(e, idx); end end def map_with_index(&block) dup.map_with_index!(&block) end end