From e0d169e679777c7af200bf0df6e00da150122f72 Mon Sep 17 00:00:00 2001
From: alexey
Date: Sat, 8 Mar 2025 00:13:31 +0300
Subject: [PATCH] Project edit
---
app.rb | 83 +++++++++++++++++++++++++
classes/db.rb | 9 ++-
classes/gitinfo.rb | 2 -
classes/projects.rb | 13 ++++
classes/utilities.rb | 4 ++
db/migrations/202502150000000_create.rb | 13 ++++
public/js/edit_area_full.js | 2 +-
public/js/reg_syntax/mock.js | 58 +++++++++++++++++
views/prjcfged.erb | 64 +++++++++++++++++++
views/prjinfo.erb | 9 +++
views/prjspec.erb | 35 +++++++++++
11 files changed, 288 insertions(+), 4 deletions(-)
mode change 100644 => 100755 public/js/edit_area_full.js
create mode 100755 public/js/reg_syntax/mock.js
create mode 100644 views/prjcfged.erb
create mode 100644 views/prjspec.erb
diff --git a/app.rb b/app.rb
index 9bafe6f..10fde23 100644
--- a/app.rb
+++ b/app.rb
@@ -536,6 +536,7 @@ get "/prjgitf/:id/:git_id" do
end
@files_list = [{ :file => "..", :isdir => true, :fname => fn }] + @files_list
end
+ @page_name = "#{prj_info[:projname]} информация из репозитория #{git_info[:reponame]}"
@proj_info = prj_info
@proj_git_name = git_info
@file_name = filepath
@@ -553,6 +554,88 @@ get "/gitbld/:id/:git_id" do
end
get "/prjcfg/:id" do
+ unless session[:prjcfg_modal_text].nil?
+ @modal_info = session[:prjcfg_modal_info]
+ @modal_text = session[:prjcfg_modal_text]
+ session[:prjcfg_modal_info] = nil
+ session[:prjcfg_modal_text] = nil
+ end
+ prj = ProjectsActions.new(cfg.get_projects_path, db)
+ if prj.path.nil?
+ print_error_page(503, "Путь к проектам не существует")
+ else
+ prj_info = prj.get_project(params["id"])
+ if prj_info.nil?
+ print_error_page(503, "Путь к проектам не существует")
+ else
+ @page_name = "#{prj_info[:projname]} редактирование конфигурации сборки"
+ @proj_name = prj_info[:projname]
+ @proj_descr = prj_info[:descr]
+ project_cfg = prj.get_project_config(params["id"])
+ @project_cfg_tmpl = File.basename(project_cfg)
+ @file_content = File.readlines(project_cfg).join("")
+ @proj_id = prj_info[:id]
+ erb :prjcfged
+ end
+ end
+end
+
+post "/prjcfg/:id" do
+ prj = ProjectsActions.new(cfg.get_projects_path, db)
+ if prj.path.nil?
+ print_error_page(503, "Путь к проектам не существует")
+ else
+ prj_info = prj.get_project(params["id"])
+ if prj_info.nil?
+ print_error_page(503, "Путь к проектам не существует")
+ else
+ pp params
+ unless params["cancel"].nil?
+ redirect "/prjedit/#{params["id"]}"
+ else
+ if params["cfginfo"].nil? || params["cfginfo"].strip == ""
+ session[:prjcfg_modal_info] = "Ошибка сохранения файла"
+ session[:prjcfg_modal_text] = "Содержимое файла не может быть пустым"
+ redirect "/prjcfg/#{params["id"]}"
+ else
+ project_cfg = prj.get_project_config(params["id"])
+ File.open(project_cfg, "w") { |f| f.write(params["cfginfo"]) }
+ redirect "/prjcfg/#{params["id"]}"
+ end
+ end
+ end
+ end
+end
+
+get "/gitspec/:id/:git_id" do
+ prj = ProjectsActions.new(cfg.get_projects_path, db)
+ if prj.path.nil?
+ print_error_page(503, "Путь к проектам не существует")
+ else
+ repo = GitRepo.new(cfg.get_repo, db)
+ if repo.path.nil?
+ print_error_page(503, "Путь к репозиториям не существует")
+ else
+ prj_info = prj.get_project(params["id"])
+ if prj_info.nil?
+ print_error_page(503, "Путь к проектам не существует")
+ else
+ git_info = repo.get_repo_short_info_by_id(params["git_id"].to_i)
+ @spec_file = db.get_project_repo_spec(params["id"], params["git_id"])
+ @page_name = "#{prj_info[:projname]} редактирование spec для git проекта #{git_info[:reponame]}"
+ @proj_id = prj_info[:id]
+ @git_id = git_info[:id]
+ git_path = prj.get_project_path_git(prj_info[:id], git_info[:reponame])
+ @files_list = get_spec_files_in_dir(git_path)
+ current_spec_data = db.get_project_repo_spec(prj_info[:id], git_info[:id])
+ @current_spec = nil
+ unless current_spec_data.nil?
+ @current_spec = current_spec_data[:spec_name]
+ end
+ erb :prjspec
+ end
+ end
+ end
end
not_found do
diff --git a/classes/db.rb b/classes/db.rb
index 5c704e1..ffd959a 100644
--- a/classes/db.rb
+++ b/classes/db.rb
@@ -18,6 +18,9 @@ end
class ReposProjects < Sequel::Model(:repos_projects)
end
+class ProjectsReposSpec < Sequel::Model(:projects_repos_spec)
+end
+
class DBase
attr :error, :last_id
@@ -34,7 +37,7 @@ class DBase
end
def get_repo_info_by_name(repo_name)
- Repos.where(reponame: repo_name)
+ Repos.where(reponame: repo_name).first
end
def get_repo_info_by_id(id)
@@ -159,4 +162,8 @@ class DBase
@last_id = id
end
end
+
+ def get_project_repo_spec(prj_id, git_id)
+ ProjectsReposSpec.where(proj_id: prj_id.to_i, repo_id: git_id.to_i).first
+ end
end
diff --git a/classes/gitinfo.rb b/classes/gitinfo.rb
index 7c939df..b3173ff 100644
--- a/classes/gitinfo.rb
+++ b/classes/gitinfo.rb
@@ -65,13 +65,11 @@ class GitRepo
repo_name = File.basename(fl, ".git")
db_info = @db.get_repo_info_by_name(repo_name)
unless db_info.nil?
- db_info = db_info.first
repos_data << { :reponame => db_info.reponame, :descr => db_info.descr, :public => db_info.public, :id => db_info.id }
else
result = create_git_db_only(repo_name)
if result.nil?
db_info = @db.get_repo_info_by_name(repo_name)
- db_info = db_info.first
repos_data << { :reponame => db_info.reponame, :descr => db_info.descr, :public => db_info.public, :id => db_info.id }
end
end
diff --git a/classes/projects.rb b/classes/projects.rb
index 3e9fc15..3e0437f 100644
--- a/classes/projects.rb
+++ b/classes/projects.rb
@@ -59,6 +59,19 @@ class ProjectsActions
fname
end
+ def get_project_config(id)
+ @error = nil
+ fname = nil
+ prj = @db.proj(id)
+ if prj.nil?
+ @error = "Проекта с id = #{id} не существует"
+ else
+ fname = File.expand_path("#{prj[:projname]}.prj", @path)
+ fname = File.join(fname, PROJECTS_STRUCTURE[:CONFIGS], "#{prj[:projname]}.cfg")
+ end
+ fname
+ end
+
def get_project_path_git(id, gitname)
proj_path = get_project_path(id)
File.join(proj_path, PROJECTS_STRUCTURE[:SRC], gitname)
diff --git a/classes/utilities.rb b/classes/utilities.rb
index 53ef905..1a02502 100644
--- a/classes/utilities.rb
+++ b/classes/utilities.rb
@@ -30,3 +30,7 @@ def check_safe_path(filename)
home_dir = Dir.home
filename.start_with?("/etc/mock") || filename.start_with?(current_dir) || filename.start_with?(home_dir)
end
+
+def get_spec_files_in_dir(directory)
+ Dir.glob(File.join(directory, "**", "*")).reject { |f| File.directory?(f) }.select { |f| File.extname(f) == ".spec" }.map { |f| f.delete_prefix(directory + "/") }
+end
diff --git a/db/migrations/202502150000000_create.rb b/db/migrations/202502150000000_create.rb
index 2c190f9..1445e92 100644
--- a/db/migrations/202502150000000_create.rb
+++ b/db/migrations/202502150000000_create.rb
@@ -63,5 +63,18 @@ Sequel.migration do
foreign_key :rpm_id, :rpms, :key => :id
primary_key [:build_id, :rpm_id]
end
+
+ create_table(:projects_projects) do
+ foreign_key :proj_id, :projects, :key => :id
+ foreign_key :proj_id_repository, :projects, :key => :id
+ primary_key [:proj_id, :proj_id_repository]
+ end
+
+ create_table(:projects_repos_spec) do
+ foreign_key :proj_id, :projects, :key => :id
+ foreign_key :repo_id, :repos, :key => :id
+ String :spec_name, :null => false, text: true
+ primary_key [:proj_id, :repo_id]
+ end
end
end
diff --git a/public/js/edit_area_full.js b/public/js/edit_area_full.js
old mode 100644
new mode 100755
index 1b5bf0f..e1ac904
--- a/public/js/edit_area_full.js
+++ b/public/js/edit_area_full.js
@@ -1,5 +1,5 @@
function EAL() {
- var t = this; t.version = "0.8.2"; date = new Date(); t.start_time = date.getTime(); t.win = "loading"; t.error = false; t.baseURL = ""; t.template = ""; t.lang = {}; t.load_syntax = {}; t.syntax = {}; t.loadedFiles = []; t.waiting_loading = {}; t.scripts_to_load = []; t.sub_scripts_to_load = []; t.syntax_display_name = { 'basic': 'Basic', 'brainfuck': 'Brainfuck', 'c': 'C', 'coldfusion': 'Coldfusion', 'cpp': 'CPP', 'css': 'CSS', 'html': 'HTML', 'java': 'Java', 'js': 'Javascript', 'pas': 'Pascal', 'perl': 'Perl', 'php': 'Php', 'python': 'Python', 'robotstxt': 'Robots txt', 'ruby': 'Ruby', 'sql': 'SQL', 'tsql': 'T-SQL', 'vb': 'Visual Basic', 'xml': 'XML', 'bash': 'Bash' }; t.resize = []; t.hidden = {}; t.default_settings = { debug: false, smooth_selection: true, font_size: "10", font_family: "monospace", start_highlight: false, toolbar: "search,go_to_line,fullscreen,|,undo,redo,|,select_font,|,change_smooth_selection,highlight,reset_highlight,word_wrap,|,help", begin_toolbar: "", end_toolbar: "", is_multi_files: false, allow_resize: "both", show_line_colors: false, min_width: 400, min_height: 125, replace_tab_by_spaces: false, allow_toggle: true, language: "en", syntax: "", syntax_selection_allow: "basic,brainfuck,c,coldfusion,cpp,css,html,java,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml,bash", display: "onload", max_undo: 30, browsers: "known", plugins: "", gecko_spellcheck: false, fullscreen: false, is_editable: true, cursor_position: "begin", word_wrap: false, autocompletion: false, load_callback: "", save_callback: "", change_callback: "", submit_callback: "", EA_init_callback: "", EA_delete_callback: "", EA_load_callback: "", EA_unload_callback: "", EA_toggle_on_callback: "", EA_toggle_off_callback: "", EA_file_switch_on_callback: "", EA_file_switch_off_callback: "", EA_file_close_callback: "" }; t.advanced_buttons = [['new_document', 'newdocument.gif', 'new_document', false], ['search', 'search.gif', 'show_search', false], ['go_to_line', 'go_to_line.gif', 'go_to_line', false], ['undo', 'undo.gif', 'undo', true], ['redo', 'redo.gif', 'redo', true], ['change_smooth_selection', 'smooth_selection.gif', 'change_smooth_selection_mode', true], ['reset_highlight', 'reset_highlight.gif', 'resync_highlight', true], ['highlight', 'highlight.gif', 'change_highlight', true], ['help', 'help.gif', 'show_help', false], ['save', 'save.gif', 'save', false], ['load', 'load.gif', 'load', false], ['fullscreen', 'fullscreen.gif', 'toggle_full_screen', false], ['word_wrap', 'word_wrap.gif', 'toggle_word_wrap', true], ['autocompletion', 'autocompletion.gif', 'toggle_autocompletion', true]]; t.set_browser_infos(t); if (t.isIE >= 6 || t.isGecko || (t.isWebKit && !t.isSafari < 3) || t.isOpera >= 9 || t.isCamino) t.isValidBrowser = true;
+ var t = this; t.version = "0.8.2"; date = new Date(); t.start_time = date.getTime(); t.win = "loading"; t.error = false; t.baseURL = ""; t.template = ""; t.lang = {}; t.load_syntax = {}; t.syntax = {}; t.loadedFiles = []; t.waiting_loading = {}; t.scripts_to_load = []; t.sub_scripts_to_load = []; t.syntax_display_name = { 'basic': 'Basic', 'brainfuck': 'Brainfuck', 'c': 'C', 'coldfusion': 'Coldfusion', 'cpp': 'CPP', 'css': 'CSS', 'html': 'HTML', 'java': 'Java', 'js': 'Javascript', 'pas': 'Pascal', 'perl': 'Perl', 'php': 'Php', 'python': 'Python', 'robotstxt': 'Robots txt', 'ruby': 'Ruby', 'sql': 'SQL', 'tsql': 'T-SQL', 'vb': 'Visual Basic', 'xml': 'XML', 'bash': 'Bash', 'mock': 'Mock' }; t.resize = []; t.hidden = {}; t.default_settings = { debug: false, smooth_selection: true, font_size: "10", font_family: "monospace", start_highlight: false, toolbar: "search,go_to_line,fullscreen,|,undo,redo,|,select_font,|,change_smooth_selection,highlight,reset_highlight,word_wrap,|,help", begin_toolbar: "", end_toolbar: "", is_multi_files: false, allow_resize: "both", show_line_colors: false, min_width: 400, min_height: 125, replace_tab_by_spaces: false, allow_toggle: true, language: "en", syntax: "", syntax_selection_allow: "basic,brainfuck,c,coldfusion,cpp,css,html,java,js,pas,perl,php,python,ruby,robotstxt,sql,tsql,vb,xml,bash, mock", display: "onload", max_undo: 30, browsers: "known", plugins: "", gecko_spellcheck: false, fullscreen: false, is_editable: true, cursor_position: "begin", word_wrap: false, autocompletion: false, load_callback: "", save_callback: "", change_callback: "", submit_callback: "", EA_init_callback: "", EA_delete_callback: "", EA_load_callback: "", EA_unload_callback: "", EA_toggle_on_callback: "", EA_toggle_off_callback: "", EA_file_switch_on_callback: "", EA_file_switch_off_callback: "", EA_file_close_callback: "" }; t.advanced_buttons = [['new_document', 'newdocument.gif', 'new_document', false], ['search', 'search.gif', 'show_search', false], ['go_to_line', 'go_to_line.gif', 'go_to_line', false], ['undo', 'undo.gif', 'undo', true], ['redo', 'redo.gif', 'redo', true], ['change_smooth_selection', 'smooth_selection.gif', 'change_smooth_selection_mode', true], ['reset_highlight', 'reset_highlight.gif', 'resync_highlight', true], ['highlight', 'highlight.gif', 'change_highlight', true], ['help', 'help.gif', 'show_help', false], ['save', 'save.gif', 'save', false], ['load', 'load.gif', 'load', false], ['fullscreen', 'fullscreen.gif', 'toggle_full_screen', false], ['word_wrap', 'word_wrap.gif', 'toggle_word_wrap', true], ['autocompletion', 'autocompletion.gif', 'toggle_autocompletion', true]]; t.set_browser_infos(t); if (t.isIE >= 6 || t.isGecko || (t.isWebKit && !t.isSafari < 3) || t.isOpera >= 9 || t.isCamino) t.isValidBrowser = true;
else t.isValidBrowser = false; t.set_base_url(); for (var i = 0; i < t.scripts_to_load.length; i++) { setTimeout("eAL.load_script('" + t.baseURL + t.scripts_to_load[i] + ".js');", 1); t.waiting_loading[t.scripts_to_load[i] + ".js"] = false; } t.add_event(window, "load", EAL.prototype.window_loaded);
}; EAL.prototype = {
has_error: function () { this.error = true; for (var i in EAL.prototype) { EAL.prototype[i] = function () { }; } }, set_browser_infos: function (o) { ua = navigator.userAgent; o.isWebKit = /WebKit/.test(ua); o.isGecko = !o.isWebKit && /Gecko/.test(ua); o.isMac = /Mac/.test(ua); o.isIE = (navigator.appName == "Microsoft Internet Explorer"); if (o.isIE) { o.isIE = ua.replace(/^.*?MSIE\s+([0-9\.]+).*$/, "$1"); if (o.isIE < 6) o.has_error(); } if (o.isOpera = (ua.indexOf('Opera') != -1)) { o.isOpera = ua.replace(/^.*?Opera.*?([0-9\.]+).*$/i, "$1"); if (o.isOpera < 9) o.has_error(); o.isIE = false; } if (o.isFirefox = (ua.indexOf('Firefox') != -1)) o.isFirefox = ua.replace(/^.*?Firefox.*?([0-9\.]+).*$/i, "$1"); if (ua.indexOf('Iceweasel') != -1) o.isFirefox = ua.replace(/^.*?Iceweasel.*?([0-9\.]+).*$/i, "$1"); if (ua.indexOf('GranParadiso') != -1) o.isFirefox = ua.replace(/^.*?GranParadiso.*?([0-9\.]+).*$/i, "$1"); if (ua.indexOf('BonEcho') != -1) o.isFirefox = ua.replace(/^.*?BonEcho.*?([0-9\.]+).*$/i, "$1"); if (ua.indexOf('SeaMonkey') != -1) o.isFirefox = (ua.replace(/^.*?SeaMonkey.*?([0-9\.]+).*$/i, "$1")) + 1; if (o.isCamino = (ua.indexOf('Camino') != -1)) o.isCamino = ua.replace(/^.*?Camino.*?([0-9\.]+).*$/i, "$1"); if (o.isSafari = (ua.indexOf('Safari') != -1)) o.isSafari = ua.replace(/^.*?Version\/([0-9]+\.[0-9]+).*$/i, "$1"); if (o.isChrome = (ua.indexOf('Chrome') != -1)) { o.isChrome = ua.replace(/^.*?Chrome.*?([0-9\.]+).*$/i, "$1"); o.isSafari = false; } }, window_loaded: function () { eAL.win = "loaded"; if (document.forms) { for (var i = 0; i < document.forms.length; i++) { var form = document.forms[i]; form.edit_area_replaced_submit = null; try { form.edit_area_replaced_submit = form.onsubmit; form.onsubmit = ""; } catch (e) { } eAL.add_event(form, "submit", EAL.prototype.submit); eAL.add_event(form, "reset", EAL.prototype.reset); } } eAL.add_event(window, "unload", function () { for (var i in eAs) { eAL.delete_instance(i); } }); }, init_ie_textarea: function (id) { var a = document.getElementById(id); try { if (a && typeof (a.focused) == "undefined") { a.focus(); a.focused = true; a.selectionStart = a.selectionEnd = 0; get_IE_selection(a); eAL.add_event(a, "focus", IE_textarea_focus); eAL.add_event(a, "blur", IE_textarea_blur); } } catch (ex) { } }, init: function (settings) { var t = this, s = settings, i; if (!s["id"]) t.has_error(); if (t.error) return; if (eAs[s["id"]]) t.delete_instance(s["id"]); for (i in t.default_settings) { if (typeof (s[i]) == "undefined") s[i] = t.default_settings[i]; } if (s["browsers"] == "known" && t.isValidBrowser == false) { return; } if (s["begin_toolbar"].length > 0) s["toolbar"] = s["begin_toolbar"] + "," + s["toolbar"]; if (s["end_toolbar"].length > 0) s["toolbar"] = s["toolbar"] + "," + s["end_toolbar"]; s["tab_toolbar"] = s["toolbar"].replace(/ /g, "").split(","); s["plugins"] = s["plugins"].replace(/ /g, "").split(","); for (i = 0; i < s["plugins"].length; i++) { if (s["plugins"][i].length == 0) s["plugins"].splice(i, 1); } t.get_template(); t.load_script(t.baseURL + "langs/" + s["language"] + ".js"); if (s["syntax"].length > 0) { s["syntax"] = s["syntax"].toLowerCase(); t.load_script(t.baseURL + "reg_syntax/" + s["syntax"] + ".js"); } eAs[s["id"]] = { "settings": s }; eAs[s["id"]]["displayed"] = false; eAs[s["id"]]["hidden"] = false; t.start(s["id"]); }, delete_instance: function (id) { var d = document, fs = window.frames, span, iframe; eAL.execCommand(id, "EA_delete"); if (fs["frame_" + id] && fs["frame_" + id].editArea) { if (eAs[id]["displayed"]) eAL.toggle(id, "off"); fs["frame_" + id].editArea.execCommand("EA_unload"); } span = d.getElementById("EditAreaArroundInfos_" + id); if (span) span.parentNode.removeChild(span); iframe = d.getElementById("frame_" + id); if (iframe) { iframe.parentNode.removeChild(iframe); try { delete fs["frame_" + id]; } catch (e) { } } delete eAs[id]; }, start: function (id) {
diff --git a/public/js/reg_syntax/mock.js b/public/js/reg_syntax/mock.js
new file mode 100755
index 0000000..7661993
--- /dev/null
+++ b/public/js/reg_syntax/mock.js
@@ -0,0 +1,58 @@
+/**
+ * Bash syntax v 1.0
+ *
+**/
+editAreaLoader.load_syntax["mock"] = {
+ 'DISPLAY_NAME': 'Mock'
+ , 'COMMENT_SINGLE': { 1: '#' }
+ , 'COMMENT_MULTI': {}
+ , 'QUOTEMARKS': { 1: "'" }
+ , 'KEYWORD_CASE_SENSITIVE': true
+ , 'KEYWORDS': {
+ 'reserved': [
+ 'config_opts', 'include', 'skip_if_unavailable', 'enabled', 'gpgcheck', 'gpgkey',
+ 'metalink', 'baseurl', 'name', 'cost', 'keepcache', 'debuglevel', 'reposdir',
+ 'logfile', 'retries', 'obsoletes', 'assumeyes', 'syslog_ident', 'syslog_device'
+ ]
+ }
+ , 'OPERATORS': [
+ '=',
+ ]
+ , 'DELIMITERS': [
+ ]
+ , 'REGEXPS': {
+ 'constants': {
+ 'search': '()({%.*%})()'
+ , 'class': 'constants'
+ , 'modifiers': 'g'
+ , 'execute': 'before'
+ }
+ , 'numbers': {
+ 'search': '()({.*})()'
+ , 'class': 'numbers'
+ , 'modifiers': 'g'
+ , 'execute': 'before'
+ }
+ , 'symbols': {
+ 'search': '()(:\\w+)()'
+ , 'class': 'symbols'
+ , 'modifiers': 'g'
+ , 'execute': 'before'
+ }
+ }
+ , 'STYLES': {
+ 'COMMENTS': 'color: #AAAAAA;'
+ , 'QUOTESMARKS': 'color: #660066;'
+ , 'KEYWORDS': {
+ 'reserved': 'font-weight: bold; color: #0000FF;'
+ }
+ , 'OPERATORS': 'color: #993300;'
+ , 'DELIMITERS': 'color: #993300;'
+ , 'REGEXPS': {
+ 'variables': 'color: #E0BD54;'
+ , 'numbers': 'color: green;'
+ , 'constants': 'color: #00AA00;'
+ , 'symbols': 'color: #879EFA;'
+ }
+ }
+};
diff --git a/views/prjcfged.erb b/views/prjcfged.erb
new file mode 100644
index 0000000..58d3a5b
--- /dev/null
+++ b/views/prjcfged.erb
@@ -0,0 +1,64 @@
+<%= erb :header %>
+
+
+
+
+ <%= @proj_name %>
+
+