111
发布时间 2023-04-23 17:35:40作者: yangxl-dev
<html lang='zh-CN'>
<head>
<title>README.md · yangxl/py-hcl-web - Gitee.com</title>
<meta content='on' http-equiv='x-dns-prefetch-control'>
<link href='//e.gitee.com' rel='dns-prefetch'>
<link href='//files.gitee.com' rel='dns-prefetch'>
<link href='//toscode.gitee.com' rel='dns-prefetch'>
<link href='https://cn-assets.gitee.com' rel='dns-prefetch'>
<link href='https://portrait.gitee.com' rel='dns-prefetch'>
<link rel="shortcut icon" type="image/vnd.microsoft.icon" href="https://cn-assets.gitee.com/assets/favicon-9007bd527d8a7851c8330e783151df58.ico" />
<link rel="canonical" href="https://gitee.com/yangxl6/py-hcl-web" />
<meta content='gitee.com/yangxl6/py-hcl-web git https://gitee.com/yangxl6/py-hcl-web.git' name='go-import'>
<meta charset='utf-8'>
<meta content='always' name='referrer'>
<meta content='Gitee' property='og:site_name'>
<meta content='Object' property='og:type'>
<meta content='https://gitee.com/yangxl6/py-hcl-web/blob/master/README.md' property='og:url'>
<meta content='https://gitee.com/static/images/logo_themecolor.png' itemprop='image' property='og:image'>
<meta content='README.md · yangxl/py-hcl-web - Gitee.com' itemprop='name' property='og:title'>
<meta content='15mHCL python' property='og:description'>
<meta content='15mHCL python' itemprop='description' name='Description'>
<meta content='pc,mobile' name='applicable-device'>
<meta content="IE=edge" http-equiv="X-UA-Compatible" />
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="e19oIg+jvVJgtr6x+vCkQpB4VMS9hvu35TEtTKTvP7CDa22mHRnQN2atkiCpx4B4o9mAXwp177kBgbqFIcKxAA==" />
<link rel="stylesheet" media="all" href="https://cn-assets.gitee.com/assets/application-16de23e9fc62f6c2d13e1cb3f6f4cebc.css" />
<script>
//<![CDATA[
window.gon = {};gon.locale="zh-CN";gon.sentry_dsn=null;gon.baidu_register_hm_push=null;gon.sensor={"server_url":"https://haveaniceday.gitee.com:3443/sa?project=production","sdk_url":"https://cn-assets.gitee.com/assets/static/sensors-sdk-2f850fa5b654ad55ac0993fda2f37ba5.js","page_type":"其他"};gon.info={"controller_path":"blob","action_name":"show","current_user":{"id":1363048,"name":"yangxl","username":"yangxl6","official":false,"admin":false,"avatar_url":"https://foruda.gitee.com/avatar/1676964465453705165/1363048_yangxl6_1633874337.png"}};gon.tour_env={"current_user":"yangxl6","action_name":"show","original_url":"https://gitee.com/yangxl6/py-hcl-web/blob/master/README.md","controller_path":"blob"};gon.http_clone="https://gitee.com/yangxl6/py-hcl-web.git";gon.user_project="yangxl6/py-hcl-web";gon.manage_branch="管理分支";gon.manage_tag="管理标签";gon.enterprise_id=0;gon.create_reaction_path="/yangxl6/py-hcl-web/reactions";gon.ipipe_base_url="https://go-api.gitee.com";gon.artifact_base_url="https://go-repo.gitee.com";gon.gitee_go_remote_url="https://go.gitee.com/assets";gon.gitee_go_active=false;gon.current_project_is_mirror=false;gon.show_repo_comment=false;gon.diagram_viewer_path="https://diagram-viewer.giteeusercontent.com";gon.ref="master";
//]]>
</script>
<script src="https://cn-assets.gitee.com/assets/static/sensor-6269b9ad61bbcdaff20078e5dcff62d5.js"></script>
<script src="https://cn-assets.gitee.com/assets/static/sentry-5.1.0-a823fb0be1b61c5d7ca4a89f0536cb0a.js"></script>
<script src="https://cn-assets.gitee.com/assets/application-2e6902d4d3d0569ecd6f6bd4f6a06f7f.js"></script>
<script src="https://cn-assets.gitee.com/assets/lib/jquery.timeago.zh-CN-4a4818e98c1978d2419ab19fabcba740.js"></script>
<link rel="stylesheet" media="all" href="https://cn-assets.gitee.com/assets/projects/application-46b94c31ba11ae8c37eacce2bdb5603e.css" />
<script src="https://cn-assets.gitee.com/assets/projects/app-2b3d989fcf407be52d8dfd35c2298749.js"></script>
<script src="//res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type='text/x-mathjax-config'>
MathJax.Hub.Config({
tex2jax: {
inlineMath: [['$','$'], ['\\(','\\)']],
displayMath: [["$$","$$"],["\\[","\\]"]],
processEscapes: true,
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code'],
ignoreClass: "container|files",
processClass: "markdown-body"
}
});
</script>
<script src="https://cn-assets.gitee.com/uploads/resources/MathJax-2.7.2/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script>
var userAgent = navigator.userAgent;
var isLessIE11 = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;
if(isLessIE11){
var can_access = ""
if (can_access != "true"){
window.location.href = "/incompatible.html";
}
}
document.addEventListener("error", function (ev) {
var elem = ev.target;
if (elem.tagName.toLowerCase() === 'img') {
elem.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAAAAACIM/FCAAACh0lEQVR4Ae3ch5W0OgyG4dt/mQJ2xgQPzJoM1m3AbALrxzrf28FzsoP0HykJEEAAAUQTBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEkKK0789+GK/I2ezfQB522PnS1qc8pGgXvr4tE4aY0XOUWlGImThWgyCk6DleixzE7qwBkg/MGiDPlVVAyp1VQGrPKiACDhFI6VkF5LmzCki+sg7IwDoglnVAil0IMkeG9CyUiwsxLFUVFzJJOQaKCjFCDN9RXMjIX7W6ztZXZDKKCyn8sWJvH+nca7WHDN9lROlAliPH9iRKCPI4cswFJQWxB46toLQgQ9jhn5QYZA9DOkoMUoQde5YapAxDWkoNYsOQR3KQd9CxUnIQF4S49CB9ENKlBxmDEKsFUgMCCCCAAHIrSF61f6153Ajy8nyiPr8L5MXnmm4CyT2fzN4DUvHZ+ntA2tOQBRBAAAEEEEAAAQQQ7ZBaC6TwSiDUaYHQ2yuB0MN+ft+43whyrs4rgVCjBUKTFshLC6TUAjGA3AxSaYFYLZBOC2RUAsk8h5qTg9QcbEoOsoQhQ2qQhsO5xCD5dgB5JQaZ+KBKGtKecvR81Ic0ZDjByKdDx0rSEDZ/djQbH+bkIdvfJFm98BfV8hD2zprfVdlu9PxVeyYAkciREohRAplJCaRSAplJCcQogTjSAdlyHRBvSAekJR0QRzogA+mADJkOiCPSAPEtqYBshlRAXC43hxix2QiOuEZkVERykGyNo9idIZKE0HO7XrG6OiMShlDWjstVzdPgXtUH9v0CEidAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQAABBBBAAAEEEEAAAQQQQP4HgjZxTpdEii0AAAAASUVORK5CYII=";
}
}, true);
</script>
</head>
<body class='git-project lang-zh-CN'>
<script>
var can_search_in_repo = 0,
repo = "",
reponame = "";
$(function() {
var $search = $('#navbar-search-form .ui.search');
$search.search({
apiSettings: {
url: '/search/relative_project?q={query}',
onResponse: function (res) {
if (res && res.status === 200 && res.data) {
var query = htmlSafe($search.search('get value'));
res.data.map(function (item) {
item.path_ns = '/' + item.path_ns;
item.icon = 'iconfont icon-project-public';
});
res.data.unshift({
name_ns: "在全站搜索 <b class='hl'>" + query +"</b> 相关项目",
path_ns: '/search?fork_filter=on&q=' + query,
icon: 'iconfont icon-search'
});
return res;
} else {
return { data: [] };
}
}
},
fields: {
results: 'data',
description: 'name_ns',
url: 'path_ns',
icon: 'icon'
},
minCharacters: 1,
maxResults: 10,
searchDelay: 250,
showNoResults: false,
transition: 'fade'
});
});
</script>
<div class='item ui dropdown empty' data-count-path='/notifications/unread_count' data-enable data-mark-notice-path='/notifications/mark' id='notice-dropdown'>
<a class="remind-button" href="/notifications">
<div class='notice-count total'></div>
</a><div class='notice-dropdown-panel menu'>
<div class='notice-dropdown-panel-header'>
<div class='tab active' data-data-path='/notifications/notices?scope=referer' data-html-path='/notifications/referer' data-scope='referer'>
<div class='content'>
@ 我
<div class='notice-count referer'></div>
</div>
</div>
<div class='tab' data-data-path='/notifications/notices?scope=infos' data-html-path='/notifications/infos' data-scope='infos'>
<div class='content'>
通知
<div class='notice-count infos'></div>
</div>
</div>
<div class='tab' data-data-path='/notifications/notices?scope=messages' data-html-path='/notifications/messages' data-scope='messages'>
<div class='content'>
私信
<div class='notice-count messages'></div>
</div>
</div>
</div>
<div class='item notice-dropdown-panel-container'>
<div class='ui dimmer over active'>
<div class='ui loader'></div>
</div>
<div class='notice-list'></div>
<div class='notice-dropdown-panel-blank'>
暂没有新消息
</div>
</div>
<div class='notice-dropdown-panel-footer'>
<div class='action'>
<div class='side left'>
<a class="mark-notices" href="javascript: void(0);">当前标记为已读
</a></div>
<div class='side right'>
<a class="load-all" target="_blank" href="javascript: void(0);">查看全部
</a></div>
</div>
</div>
</div>
</div>
<script>
$('.destroy-user-session').on('click', function() {
$.cookie('access_token', null, { path: '/' });
})
</script>
</div>
</div>
</div>
</header>
<script>
Gitee.initNavbar()
Gitee.initRepoRemoteWay()
$.cookie('user_locale',null)
</script>
<script>
var userAgent = navigator.userAgent;
var isLessIE11 = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1;
if(isLessIE11){
var can_access = ""
if (can_access != "true"){
window.location.href = "/incompatible.html";
}
}
</script>
<div class='fixed-notice-infos'>
<div class='all-messages'>
</div>
<script>
(function() {
$(function() {
var $error_box, alertTip, notify_content, notify_options, template;
template = '<div data-notify="container" class="ui {0} message" role="alert">' + '<i data-notify="dismiss" class="close icon"></i>' + '<span data-notify="message">{2}</span>' + '</div>';
notify_content = {
"message": "更新成功"
};
notify_options = {
"type": "info"
};
alertTip = '';
$error_box = $(".flash_error.flash_error_box");
if (notify_options.type === 'error' && $error_box.length > 0 && !$.isEmptyObject(notify_content.message)) {
if (notify_content.message === 'captcha_fail') {
alertTip = "验证码不正确";
} else if (notify_content.message === 'captcha_expired') {
alertTip = "验证码已过期,请点击刷新";
} else if (notify_content.message === 'not_found_in_database') {
alertTip = "帐号或者密码错误";
} else if (notify_content.message === 'not_found_and_show_captcha') {
alertTip = "帐号或者密码错误";
} else if (notify_content.message === 'phone_captcha_fail') {
alertTip = "手机验证码不通过";
} else {
alertTip = notify_content.message;
}
return $error_box.html(alertTip).show();
} else if (notify_content) {
if ("show" === 'third_party_binding') {
return $('#third_party_binding-message').html(notify_content.message).addClass('ui message red');
}
notify_options.delay = 3000;
notify_options.template = template;
notify_options.offset = {
x: 10,
y: 30
};
notify_options.element = '#messages-container';
return $.notify(notify_content, notify_options);
}
});
}).call(this);
</script>
</div>
<script>
(function() {
$(function() {
var setCookie;
setCookie = function(name, value) {
$.cookie(name, value, {
path: '/',
expires: 365
});
};
$('#remove-bulletin, #remove-bulletin-dashboard').on('click', function() {
setCookie('remove_bulletin', "gitee-maintain-1677815209");
$('#git-bulletin').hide();
});
$('#remove-member-bulletin').on('click', function() {
setCookie('remove_member_bulletin', "gitee_member_bulletin");
$(this).parent().hide();
});
return $('#remove-gift-bulletin').on('click', function() {
setCookie('remove_gift_bulletin', "gitee-gift-bulletin");
$(this).parent().hide();
});
});
}).call(this);
</script>
<script>
function closeMessageBanner(pthis, type, val) {
var json = {}
val = typeof val === 'undefined' ? null : val
$(pthis).parent().remove()
if (type === 'out_of_enterprise_member') {
json = {type: type, data: val}
} else if (type === 'enterprise_overdue') {
json = {type: type, data: val}
}
$.post('/profile/close_flash_tip', json)
}
</script>
<div class='git-project-desc-wrapper'>
<script>
$('.git-project-desc-wrapper .ui.dropdown').dropdown();
if (false) {
gon.project_new_blob_path = "/yangxl6/py-hcl-web/new/master/README.md"
bindShowModal({
el: $('.no-license .project-license__create'),
complete: function(data, modal) {
if (!data.haveNoChoice && !data.data) {
Flash.show('请选择一项开源许可证')
} else {
location.href = gon.project_new_blob_path + '?license=' + data.data
}
},
skip: function () {
location.href = gon.project_new_blob_path + '?license'
}
});
}
$(".project-admin-action-box .reject").click(function() {
var reason = $('[name=review-reject-reason]').val();
if (!reason) {
Flash.error('请选择不通过理由')
return
}
$.ajax({
type: 'POST',
url: "/admin/shumei_content/shumei_check/reject_project_public",
data: {
reason: reason,
status: 'rejected',
project_id: 28146876
},
success: function(result){
if(result.status == 'success'){
window.location.reload();
}else{
Flash.error(result.message)
}
}
})
})
$(".project-admin-action-box .approve").click(function(){
$.ajax({
type: 'POST',
url: "/admin/shumei_content/shumei_check/reject_project_public",
data: {
status: 'approved',
project_id: 28146876
},
success: function(result){
if(result.status == 'success'){
window.location.reload();
}else{
Flash.error(result.message)
}
}
})
})
$(".project-admin-action-box .waiting").click(function(){
$.ajax({
type: 'POST',
url: "/admin/shumei_content/shumei_check/reject_project_public",
data: {
status: 'waiting',
project_id: 28146876
},
success: function(result){
if(result.status == 'success'){
window.location.reload();
}else{
Flash.error(result.message)
}
}
})
})
$('i.help.circle.icon').popup({
popup: '.no-license .ui.popup',
position: 'right center'
});
$('#remove-no-license-message').on('click', function() {
$.cookie("skip_repo_no_license_message_28146876", 'hide', { expires: 365 });
$('#user-no-license-message').hide();
return;
});
</script>
</div>
</div>
<input type="hidden" name="path" id="path" value="README.md" />
<input type="hidden" name="ref" id="ref" value="master" />
</div>
<style>
.iconfont.icon-shieldlock {
color: #8c92a4;
}
</style>
<script>
var $branchesDropdown = $('#branches_panel');
var $searchNameInput = $('.search-branch');
var concurrentRequestLock = false;
var filterXSS = window.filterXSS;
$branchesDropdown.scroll(function() {
var branchesPanel = document.getElementById('branches_panel');
var numOfBranches = $branchesDropdown.children().length;
var pageToken = $branchesDropdown.children().last().text().trim();
if (branchesPanel.clientHeight + branchesPanel.scrollTop + 37 > branchesPanel.scrollHeight && numOfBranches < 1) {
loadData({ page_token: pageToken });
}
});
$searchNameInput.on('input', window.globalUtils.debouce(function (e) {
var $currentTab = $('.tab-menu-action.active');
var numOfBranches = $branchesDropdown.children().length;
if($currentTab.data('tab') === 'branches' && numOfBranches < 1) {
var searchWord = $searchNameInput.val().trim();
if (searchWord !== "") {
loadData({ search: searchWord });
} else {
loadData({});
}
}
}, 500));
function loadData(data) {
if (concurrentRequestLock) { return; }
concurrentRequestLock = true;
$.ajax({
url: "/yangxl6/py-hcl-web/branches/load_more",
type: 'GET',
data: data,
dataType: 'json',
success: function (branches) {
var html = '';
var protectRule = '';
if (data.search || !data.page_token) {
$branchesDropdown.empty();
}
branches.forEach(function (branch) {
var branchName = filterXSS(branch.name);
if(branch.branch_type.value === 1) {
var rule = filterXSS(branch.protection_rule.wildcard);
protectRule = `<i
class="iconfont icon-shieldlock protected-branch-popup"
data-title="受保护分支"
data-content='保护规则: ${rule}'
>
</i>`
}
html += `<div data-value='${branchName}' class="item">
<span>${branchName}</span> ${protectRule}
</div>`
});
$branchesDropdown.append(html);
$('.protected-branch-popup').popup()
},
complete: function () {
concurrentRequestLock = false;
}
});
}
</script>
<script>
$(function () {
Gitee.initTabsInDropdown($('#git-project-branch').dropdown({
fullTextSearch: true,
selectOnKeydown: true,
action: function (text,value,el) {
var oItemOrInitObject = el[0] || el
var isNotSelect = oItemOrInitObject.dataset.tab && oItemOrInitObject.dataset.tab === 'branches'
if(isNotSelect){
console.warn("You didn't choose a branch")
return
}
var path = $('#path').val();
var href = ['/yangxl6/py-hcl-web/tree', encodeURIComponent(value), path].join('/');
window.location.href = href;
return true
},
onNoResults: function (searchTerm) {
//未找到结果
return true
},
}));
$('.protected-branch-popup').popup()
})
</script>
</div>
</div>
<div class='git-project-right-actions pull-right'>
<div class='git-project-download-panel for-project ui bottom right popup'>
<div class='ui small secondary pointing menu'>
<a class='item active' data-text='' data-type='http' data-url='https://gitee.com/yangxl6/py-hcl-web.git'>HTTPS</a>
<a class='item' data-text='' data-type='ssh' data-url='git@gitee.com:yangxl6/py-hcl-web.git'>SSH</a>
<a class='item' data-text="该仓库未启用SVN访问,请仓库管理员前往【<a target='_blank' href=/yangxl6/py-hcl-web/settings>仓库设置</a>】开启。" data-type='svn' data-url=''>SVN</a>
<a class='item' data-text="该仓库未启用SVN访问,请仓库管理员前往【<a target='_blank' href=/yangxl6/py-hcl-web/settings>仓库设置</a>】开启。" data-type='svn_ssh' data-url=''>SVN+SSH</a>
</div>
<div class='ui fluid right labeled small input download-url-panel'>
<input type="text" name="project_clone_url" id="project_clone_url" value="https://gitee.com/yangxl6/py-hcl-web.git" onclick="focus();select()" readonly="readonly" />
<div class='ui basic label'>
<div class='ui small basic orange button' data-clipboard-target='#project_clone_url' id='btn-copy-clone-url'>
复制
</div>
</div>
</div>
<div class='ui fluid right labeled warning-text forbid-warning-text'>
</div>
<hr>
<a class="ui fluid tiny download link button" sa_evt="repoDownload" sa_repo_id="28146876" sa_is_self="true" sa_is_member="true" href="/yangxl6/py-hcl-web/repository/archive/master.zip"><i class='icon download'></i>
下载ZIP
</a></div>
<script>
(function() {
var $btnClone, $btnCopy, $input, $panel;
$btnClone = $('#btn-dl-or-clone');
$panel = $('.git-project-download-panel');
$input = $('#project_clone_url');
$btnCopy = $('#btn-copy-clone-url');
$btnClone.popup({
on: 'click',
hoverable: true,
position: 'bottom center'
});
$panel.find('.menu > .item').on('click', function(e) {
var $item, dataUrl;
$item = $(this).addClass('active');
$item.siblings().removeClass('active');
dataUrl = $item.attr('data-url');
if (dataUrl) {
$panel.find('.download-url-panel').show();
$input.val(dataUrl);
$panel.find('.forbid-warning-text').html('');
} else {
$panel.find('.download-url-panel').hide();
$panel.find('.forbid-warning-text').html($item.attr('data-text') || '');
}
return $.cookie('remote_way', $item.attr('data-type'), {
expires: 365,
path: '/'
});
}).filter('[data-type="' + ($.cookie('remote_way') || 'http') + '"]').trigger('click');
new Clipboard($btnCopy[0]).on('success', function() {
$btnCopy.popup({
content: '已复制',
position: 'right center',
onHidden: function() {
return $btnCopy.popup('destroy');
}
});
return $btnCopy.popup('show');
});
}).call(this);
</script>
</div>
<div class='d-inline pull-right' id='git-project-root-actions'>
<script>
$('.disabled-upload-readonly').popup({
content: "只读目录不允许上传文件",
className: {
popup: 'ui popup',
},
position: 'bottom center',
})
$('.disabled-create-folder').popup({
content: "只读目录不允许创建目录",
className: {
popup: 'ui popup',
},
position: 'bottom center',
})
$('.disabled-create-file').popup({
content: "只读目录不允许创建文件",
className: {
popup: 'ui popup',
},
position: 'bottom center',
})
$('.disabled-create-submodule').popup({
content: "只读目录不允许创建子模块",
className: {
popup: 'ui popup',
},
position: 'bottom center',
})
$('.disabled-upload-readonly, .disabled-create-folder, .disabled-create-file, .disabled-create-submodule').click(function() {
return false
})
</script>
<style>
.disabled-upload-readonly, .disabled-create-file, .disabled-create-folder, .disabled-create-submodule {
background-color: #dcddde !important;
color: rgba(0, 0, 0, 0.4) !important;
opacity: 0.3 !important;
background-image: none !important;
-webkit-box-shadow: none !important;
box-shadow: none !important; }
</style>
</div>
<style>
#btn-copy-file-path {
vertical-align: middle;
cursor: pointer;
}
</style>
<script>
$btnCopy = $('#btn-copy-file-path')
$btnCopy.popup({
content: '复制路径'
})
if ($btnCopy[0]) {
new Clipboard($btnCopy[0]).on('success', function() {
$btnCopy.popup('destroy').popup({
content: '已复制',
on: 'manual'
}).popup('show');
setTimeout(function () {
$btnCopy.popup('destroy').popup({
content: '复制路径'
});
}, 2000)
});
}
</script>
</div>
<div class='ui horizontal list repo-action-list branches-tags' style='display: none;'>
<div class='item'>
<a class="ui blank button" href="/yangxl6/py-hcl-web/branches"><i class='iconfont icon-branches'></i>
分支 1
</a></div>
<div class='item mr-3'>
<a class="ui blank button" href="/yangxl6/py-hcl-web/tags"><i class='iconfont icon-tag'></i>
标签 0
</a></div>
</div>
</div>
<script>
if(window.gon.locale == 'en')
$('.branches-tags').css('margin-top', '12px')
</script>
<style>
.ui.dropdown .menu > .header {
text-transform: none; }
</style>
<script>
$(function () {
var $tip = $('#apk-download-tip');
if (!$tip.length) {
return;
}
$tip.find('.btn-close').on('click', function () {
$tip.hide();
});
});
(function(){
function pathAutoRender() {
var $parent = $('#git-project-bread'),
$child = $('#git-project-bread').children('.ui.horizontal.list'),
mainWidth = 0;
$child.each(function (i,item) {
mainWidth += $(item).width()
});
$('.breadcrumb.path.fork-path').remove();
if (mainWidth > 995) {
$('#path-breadcrumb').hide();
$parent.append('<div class="ui breadcrumb path fork-path">' + $('#path-breadcrumb').html() + '<div/>')
} else {
$('#path-breadcrumb').show();
}
}
window.pathAutoRender = pathAutoRender;
pathAutoRender();
})();
</script>
<div class='row column tree-holder' id='tree-holder'>
<div class='tree-content-holder' id='tree-content-holder'>
<div class='file_holder'>
<div class='file_title'>
<div class='blob-header-title'>
<div class='blob-description'>
<span class='file_name' title='README.md'>
README.md
</span>
<small>803 Bytes</small>
</div>
<div class='options'>
<div class='ui mini buttons basic'>
<script>
"use strict";
try {
if((gon.wait_fork!=undefined && gon.wait_fork==true) || (gon.wait_fetch!=undefined && gon.wait_fetch==true)){
$('.edit-blob').popup({content:"当前仓库正在后台处理中,暂时无法编辑", on: 'hover', delay: { show: 200, hide: 200 }});
$('.edit-blob').click(function(e){
e.preventDefault();
})
}
var setUrl = function() {
var params = window.location.search
if (params==undefined || $.trim(params).length==0) return;
$('span.options').children('.basic').find('a').each(function(index,ele){
var origin_href = $(ele).attr('href');
if (origin_href!="#" && origin_href.indexOf('?') == -1){
$(ele).attr('href',origin_href+params);
}
});
}
setUrl();
var clipboard = null,
$btncopy = $("#copy-text");
clipboard = new Clipboard("#copy-text", {
text: function(trigger) {
return $("#blob_raw").val();
}
})
clipboard.on('success', function(e) {
$btncopy.popup('hide');
$btncopy.popup('destroy');
$btncopy.popup({content: '已复制', position: 'bottom center'});
$btncopy.popup('show');
})
clipboard.on('error', function(e) {
var giteeModal = new GiteeModalHelper({okText: '确定'});
giteeModal.alert("一键复制", '复制失败,请手动复制');
})
$(function() {
$btncopy.popup({
content: '点击复制',
position: 'bottom center'
})
})
} catch (error) {
console.log('blob/action error:' + error);
}
$('.disabled-edit-readonly').popup({
content: "只读文件不可编辑",
className: {
popup: 'ui popup',
},
position: 'bottom center',
})
$('.disabled-edit-readonly, .disabled-edit-status').click(function() {
return false
})
$('.has_tooltip').popup({
position: 'top center'
});
</script>
<style>
.disabled-edit-readonly, .disabled-edit-status {
background-color: #dcddde !important;
color: rgba(0, 0, 0, 0.4) !important;
opacity: 0.3 !important;
background-image: none !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
cursor: default !important; }
.drawio-iframe-code-card {
position: relative; }
.drawio-iframe-code-card textarea {
width: 100%;
height: 140px;
resize: none; }
.drawio-iframe-code-card .icon-clone {
position: absolute;
right: 32px;
bottom: 32px; }
.drawio-iframe-code-card iframe {
border-radius: 2px;
border: 1px solid #DEDEDF; }
</style>
</div>
</div>
<div class='blob-header-title mt-1 ubblock_tip'>
</div>
<div class='contributor-description'><span class='recent-commit' style='margin-top: 0.7rem'>
<a class="commit-author-link js-popover-card " data-username="yangxl6" href="/yangxl6">yangxl</a>
<span>提交于</span>
<span class='timeago commit-date' title='2023-04-21 07:48:21 +0000'>
2023-04-21 07:48
</span>
.
<a href="/yangxl6/py-hcl-web/commit/3a4ff396856649f314b518dd8b414542c4063b74">update README.md.</a>
</span>
</div>
</div>
<div class='clearfix'></div>
<div class='file_catalog'>
<div class='toggle'>
<i class='icon angle left'></i>
</div>
<div class='scroll-container'>
<div class='container'>
<div class='skeleton'>
<div class='line line1'></div>
<div class='line line2'></div>
<div class='line line3'></div>
<div class='line line1'></div>
<div class='line line2'></div>
<div class='line line3'></div>
</div>
</div>
</div>
</div>
<div class='file_content markdown-body'>
<h1>
<a id="user-content-codegpt" class="anchor" href="#codegpt"></a>CodeGPT</h1>
<p><a href="https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fappleboy%2FCodeGPT%2Factions%2Fworkflows%2Ftesting.yml"><img src="https://github.com/appleboy/CodeGPT/actions/workflows/testing.yml/badge.svg?branch=main" alt="Lint and Testing"></a>
<a href="https://gitee.com/link?target=https%3A%2F%2Fcodecov.io%2Fgh%2Fappleboy%2FCodeGPT"><img src="https://codecov.io/gh/appleboy/CodeGPT/branch/main/graph/badge.svg" alt="codecov"></a>
<a href="https://gitee.com/link?target=https%3A%2F%2Fgoreportcard.com%2Freport%2Fgithub.com%2Fappleboy%2FCodeGPT"><img src="https://goreportcard.com/badge/github.com/appleboy/CodeGPT" alt="Go Report Card"></a></p>
<p><img src="/mirrors/codegpt/raw/main/images/cover.png" alt="cover"></p>
<p>A CLI written in <a href="https://gitee.com/link?target=https%3A%2F%2Fgo.dev">Go</a> language that writes git commit messages or do a code review brief for you using ChatGPT AI (gpt-3.5-turbo, gpt-4 model) and automatically installs a <a href="https://gitee.com/link?target=https%3A%2F%2Fgit-scm.com%2Fdocs%2Fgithooks">git prepare-commit-msg hook</a>.</p>
<ul>
<li><a href="https://gitee.com/link?target=https%3A%2F%2Fblog.wu-boy.com%2F2023%2F03%2Fwrites-git-commit-messages-using-chatgpt%2F">繁體中文介紹</a></li>
<li><a href="https://gitee.com/link?target=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D4Yei_t6eMZU">繁體中文影片</a></li>
</ul>
<p><img src="/mirrors/codegpt/raw/main/images/flow.svg" alt="flow"></p>
<h2>
<a id="user-content-feature" class="anchor" href="#feature"></a>Feature</h2>
<ul>
<li>Support <a href="https://gitee.com/link?target=https%3A%2F%2Fazure.microsoft.com%2Fen-us%2Fproducts%2Fcognitive-services%2Fopenai-service">Azure OpenAI Service</a> or <a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Fdocs%2Fapi-reference">OpenAI API</a>.</li>
<li>Support <a href="https://gitee.com/link?target=https%3A%2F%2Fwww.conventionalcommits.org%2Fen%2Fv1.0.0%2F">conventional commits specification</a>.</li>
<li>Support Git prepare-commit-msg Hook, see the <a href="https://gitee.com/link?target=https%3A%2F%2Fgit-scm.com%2Fbook%2Fen%2Fv2%2FCustomizing-Git-Git-Hooks">Git Hooks documentation</a>.</li>
<li>Support customize generate diffs with n lines of context, the default is three.</li>
<li>Support for excluding files from the git diff command.</li>
<li>Support commit message translation into another language (support <code>en</code>, <code>zh-tw</code> or <code>zh-cn</code>).</li>
<li>Support socks proxy or custom network HTTP proxy.</li>
<li>Support <a href="https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fappleboy%2FCodeGPT%2Fblob%2Fbf28f000463cfc6dfa2572df61e1b160c5c680f7%2Fopenai%2Fopenai.go%23L18-L38">model lists</a> like <code>gpt-4</code>, <code>gpt-3.5-turbo</code> ...etc.</li>
<li>Support do a brief code review.</li>
</ul>
<p><img src="/mirrors/codegpt/raw/main/images/code_review.png" alt="code review"></p>
<h2>
<a id="user-content-installation" class="anchor" href="#installation"></a>Installation</h2>
<p>Currently, the only supported method of installation on MacOS is <a href="https://gitee.com/link?target=http%3A%2F%2Fbrew.sh%2F">Homebrew</a>. To install <code>codegpt</code> via brew:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">brew tap appleboy/tap</span>
<span id="LC2" class="line">brew <span class="nb">install </span>codegpt</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>The pre-compiled binaries can be downloaded from <a href="https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fappleboy%2FCodeGPT%2Freleases">release page</a>.Change the binary permissions to <code>755</code> and copy the binary to the system bin directory. Use the <code>codegpt</code> command as shown below.</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line"><span class="nv">$ </span>codegpt version</span>
<span id="LC2" class="line">version: v0.1.6 commit: xxxxxxx</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h2>
<a id="user-content-setup" class="anchor" href="#setup"></a>Setup</h2>
<p>Please first create your OpenAI API Key. The <a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys">OpenAI Platform</a> allows you to generate a new API Key.</p>
<p><img src="/mirrors/codegpt/raw/main/images/register.png" alt="register"></p>
<p>An environment variable is a variable that is set on your operating system, rather than within your application. It consists of a name and value.We recommend that you set the name of the variable to <code>OPENAI_API_KEY</code>.</p>
<p>See the <a href="https://gitee.com/link?target=https%3A%2F%2Fhelp.openai.com%2Fen%2Farticles%2F5112595-best-practices-for-api-key-safety">Best Practices for API Key Safety</a>.</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line"><span class="nb">export </span><span class="nv">OPENAI_API_KEY</span><span class="o">=</span>sk-xxxxxxx</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>or store your API key in custom config file.</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt config <span class="nb">set </span>openai.api_key sk-xxxxxxx</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>This will create a <code>.codegpt.yaml</code> file in your home directory ($HOME/.config/codegpt/.codegpt.yaml). The following options are available.</p>
<ul>
<li>
<strong>openai.base_url</strong>: replace the default base URL (<code>https://api.openai.com/v1</code>). You can try <code>https://closeai.deno.dev/v1</code>. See <a href="https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fjustjavac%2Fopenai-proxy">justjavac/openai-proxy</a>.</li>
<li>
<strong>openai.api_key</strong>: generate API key from <a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys">openai platform page</a>.</li>
<li>
<strong>openai.org_id</strong>: Identifier for this organization sometimes used in API requests. see <a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Faccount%2Forg-settings">organization settings</a>. only for <code>openai</code> service.</li>
<li>
<strong>openai.model</strong>: default model is <code>gpt-3.5-turbo</code>, you can change to <code>gpt-4</code> or <a href="https://gitee.com/link?target=https%3A%2F%2Fgithub.com%2Fappleboy%2FCodeGPT%2Fblob%2Fbf28f000463cfc6dfa2572df61e1b160c5c680f7%2Fopenai%2Fopenai.go%23L18-L38">other available model list</a>.</li>
<li>
<strong>openai.lang</strong>: default language is <code>en</code> and available languages <code>zh-tw</code>, <code>zh-cn</code>, <code>ja</code>.</li>
<li>
<strong>openai.proxy</strong>: http/https client proxy.</li>
<li>
<strong>openai.socks</strong>: socks client proxy.</li>
<li>
<strong>openai.timeout</strong>: default http timeout is <code>10s</code> (ten seconds).</li>
<li>
<strong>openai.max_tokens</strong>: default max tokens is <code>300</code>. see reference <a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Fdocs%2Fapi-reference%2Fcompletions%2Fcreate%23completions%2Fcreate-max_tokens">max_tokens</a>.</li>
<li>
<strong>openai.temperature</strong>: default temperature is <code>0.7</code>. see reference <a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Fdocs%2Fapi-reference%2Fcompletions%2Fcreate%23completions%2Fcreate-temperature">temperature</a>.</li>
<li>
<strong>git.diff_unified</strong>: generate diffs with <code><n></code> lines of context, default is <code>3</code>.</li>
<li>
<strong>git.exclude_list</strong>: exclude file from <code>git diff</code> command.</li>
<li>
<strong>openai.provider</strong>: default service provider is <code>openai</code>, you can change to <code>azure</code>.</li>
<li>
<strong>openai.model_name</strong>: model deployment name (for azure).</li>
</ul>
<h3>
<a id="user-content-how-to-change-to-azure-openai-service" class="anchor" href="#how-to-change-to-azure-openai-service"></a>How to change to Azure OpenAI Service</h3>
<p>Please get the <code>API key</code>, <code>Endpoint</code> and <code>Model deployments</code> list from Azure Resource Management Portal on left menu.</p>
<p><img src="/mirrors/codegpt/raw/main/images/azure_01.png" alt="azure01"></p>
<p><img src="/mirrors/codegpt/raw/main/images/azure_02.png" alt="azure02"></p>
<p>Update your config file.</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt config <span class="nb">set </span>openai.provider azure</span>
<span id="LC2" class="line">codegpt config <span class="nb">set </span>openai.base_url https://xxxxxxxxx.openai.azure.com/</span>
<span id="LC3" class="line">codegpt config <span class="nb">set </span>openai.api_key xxxxxxxxxxxxxxxx</span>
<span id="LC4" class="line">codegpt config <span class="nb">set </span>openai.model_name xxxxx-gpt-35-turbo</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h2>
<a id="user-content-usage" class="anchor" href="#usage"></a>Usage</h2>
<p>There are two methods for generating a commit message using the <code>codegpt</code> command. The first is CLI mode, and the second is Git Hook.</p>
<h3>
<a id="user-content-cli-mode" class="anchor" href="#cli-mode"></a>CLI mode</h3>
<p>You can call <code>codegpt</code> directly to generate a commit message for your staged changes:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">git add <files...></span>
<span id="LC2" class="line">codegpt commit <span class="nt">--preview</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>The commit message is shown below.</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">Summarize the commit message use gpt-3.5-turbo model</span>
<span id="LC2" class="line">We are trying to summarize a git diff</span>
<span id="LC3" class="line">We are trying to summarize a title <span class="k">for </span>pull request</span>
<span id="LC4" class="line"><span class="o">================</span>Commit <span class="nv">Summary</span><span class="o">====================</span></span>
<span id="LC5" class="line"></span>
<span id="LC6" class="line">feat: Add preview flag and remove disableCommit flag <span class="k">in </span>commit <span class="nb">command </span>and template file.</span>
<span id="LC7" class="line"></span>
<span id="LC8" class="line">- Add a <span class="sb">`</span>preview<span class="sb">`</span> flag to the <span class="sb">`</span>commit<span class="sb">`</span> <span class="nb">command</span></span>
<span id="LC9" class="line">- Remove the <span class="sb">`</span>disbaleCommit<span class="sb">`</span> flag from the <span class="sb">`</span>prepare-commit-msg<span class="sb">`</span> template file</span>
<span id="LC10" class="line"></span>
<span id="LC11" class="line"><span class="o">==================================================</span></span>
<span id="LC12" class="line">Write the commit message to .git/COMMIT_EDITMSG file</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>or translate all git commit messages into a different language (<code>Traditional Chinese</code>, <code>Simplified Chinese</code> or <code>Japanese</code>)</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt commit <span class="nt">--lang</span> zh-tw <span class="nt">--preview</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>Consider the following outcome:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">Summarize the commit message use gpt-3.5-turbo model</span>
<span id="LC2" class="line">We are trying to summarize a git diff</span>
<span id="LC3" class="line">We are trying to summarize a title <span class="k">for </span>pull request</span>
<span id="LC4" class="line">We are trying to translate a git commit message to Traditional Chinese language</span>
<span id="LC5" class="line"><span class="o">================</span>Commit <span class="nv">Summary</span><span class="o">====================</span></span>
<span id="LC6" class="line"></span>
<span id="LC7" class="line">功能:重構 codegpt commit 命令標記</span>
<span id="LC8" class="line"></span>
<span id="LC9" class="line">- 將「codegpt commit」命令新增「預覽」標記</span>
<span id="LC10" class="line">- 從「codegpt commit」命令中移除「--disableCommit」標記</span>
<span id="LC11" class="line"></span>
<span id="LC12" class="line"><span class="o">==================================================</span></span>
<span id="LC13" class="line">Write the commit message to .git/COMMIT_EDITMSG file</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>You can replace the tip of the current branch by creating a new commit. just use <code>--amend</code> flag</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt commit <span class="nt">--amend</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h2>
<a id="user-content-change-commit-message-template" class="anchor" href="#change-commit-message-template"></a>Change commit message template</h2>
<p>Default commit message template as following:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">{{ .summarize_prefix }}: {{ .summarize_title }}</span>
<span id="LC2" class="line"></span>
<span id="LC3" class="line">{{ .summarize_message }}</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>change format with template string using <code>--template_string</code> paratemter:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt commit <span class="nt">--preview</span> <span class="nt">--template_string</span> <span class="se">\</span></span>
<span id="LC2" class="line"> <span class="s2">"[{{ .summarize_prefix }}]: {{ .summarize_title }}"</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>change format with template file using <code>--template_file</code> parameter:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt commit <span class="nt">--preview</span> <span class="nt">--template_file</span> your_file_path</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h3>
<a id="user-content-git-hook" class="anchor" href="#git-hook"></a>Git hook</h3>
<p>You can also use the prepare-commit-msg hook to integrate <code>codegpt</code> with Git. This allows you to use Git normally and edit the commit message before committing.</p>
<h4>
<a id="user-content-install" class="anchor" href="#install"></a>Install</h4>
<p>You want to install the hook in the Git repository:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt hook <span class="nb">install</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h4>
<a id="user-content-uninstall" class="anchor" href="#uninstall"></a>Uninstall</h4>
<p>You want to remove the hook from the Git repository:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt hook uninstall</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>Stage your files and commit after installation:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">git add <files...></span>
<span id="LC2" class="line">git commit</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p><code>codegpt</code> will generate the commit message for you and pass it back to Git. Git will open it with the configured editor for you to review/edit it. Then, to commit, save and close the editor!</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line"><span class="nv">$ </span>git commit</span>
<span id="LC2" class="line">Summarize the commit message use gpt-3.5-turbo model</span>
<span id="LC3" class="line">We are trying to summarize a git diff</span>
<span id="LC4" class="line">We are trying to summarize a title <span class="k">for </span>pull request</span>
<span id="LC5" class="line"><span class="o">================</span>Commit <span class="nv">Summary</span><span class="o">====================</span></span>
<span id="LC6" class="line"></span>
<span id="LC7" class="line">Improve user experience and documentation <span class="k">for </span>OpenAI tools</span>
<span id="LC8" class="line"></span>
<span id="LC9" class="line">- Add download links <span class="k">for </span>pre-compiled binaries</span>
<span id="LC10" class="line">- Include instructions <span class="k">for </span>setting up OpenAI API key</span>
<span id="LC11" class="line">- Add a CLI mode <span class="k">for </span>generating commit messages</span>
<span id="LC12" class="line">- Provide references <span class="k">for </span>OpenAI Chat completions and ChatGPT/Whisper APIs</span>
<span id="LC13" class="line"></span>
<span id="LC14" class="line"><span class="o">==================================================</span></span>
<span id="LC15" class="line">Write the commit message to .git/COMMIT_EDITMSG file</span>
<span id="LC16" class="line"><span class="o">[</span>main 6a9e879] Improve user experience and documentation <span class="k">for </span>OpenAI tools</span>
<span id="LC17" class="line"> 1 file changed, 56 insertions<span class="o">(</span>+<span class="o">)</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h3>
<a id="user-content-code-review" class="anchor" href="#code-review"></a>Code Review</h3>
<p>You can use <code>codegpt</code> to generate a code review message for your staged changes:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt review</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>or translate all code review messages into a different language (<code>Traditional Chinese</code>, <code>Simplified Chinese</code> or <code>Japanese</code>)</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">codegpt review <span class="nt">--lang</span> zh-tw</span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>See the following result:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line">Code review your changes using gpt-3.5-turbo model</span>
<span id="LC2" class="line">We are trying to review code changes</span>
<span id="LC3" class="line">PromptTokens: 1021, CompletionTokens: 200, TotalTokens: 1221</span>
<span id="LC4" class="line">We are trying to translate core review to Traditional Chinese language</span>
<span id="LC5" class="line">PromptTokens: 287, CompletionTokens: 199, TotalTokens: 486</span>
<span id="LC6" class="line"><span class="o">================</span>Review <span class="nv">Summary</span><span class="o">====================</span></span>
<span id="LC7" class="line"></span>
<span id="LC8" class="line">總體而言,此程式碼修補似乎在增加 Review 指令的功能,允許指定輸出語言並在必要時進行翻譯。以下是需要考慮的潛在問題:</span>
<span id="LC9" class="line"></span>
<span id="LC10" class="line">- 輸出語言沒有進行輸入驗證。如果指定了無效的語言代碼,程式可能會崩潰或產生意外結果。</span>
<span id="LC11" class="line">- 此使用的翻譯 API 未指定,因此不清楚是否存在任何安全漏洞。</span>
<span id="LC12" class="line">- 無法處理翻譯 API 調用的錯誤。如果翻譯服</span>
<span id="LC13" class="line"></span>
<span id="LC14" class="line"><span class="o">==================================================</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>another php example code:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line"><span class="cp"><?php</span></span>
<span id="LC2" class="line"><span class="k">if</span><span class="p">(</span> <span class="k">isset</span><span class="p">(</span> <span class="nv">$_POST</span><span class="p">[</span> <span class="s1">'Submit'</span> <span class="p">]</span> <span class="p">)</span> <span class="p">)</span> <span class="p">{</span></span>
<span id="LC3" class="line"> <span class="c1">// Get input</span></span>
<span id="LC4" class="line"> <span class="nv">$target</span> <span class="o">=</span> <span class="nv">$_REQUEST</span><span class="p">[</span> <span class="s1">'ip'</span> <span class="p">];</span></span>
<span id="LC5" class="line"> <span class="c1">// Determine OS and execute the ping command.</span></span>
<span id="LC6" class="line"> <span class="k">if</span><span class="p">(</span> <span class="nb">stristr</span><span class="p">(</span> <span class="nb">php_uname</span><span class="p">(</span> <span class="s1">'s'</span> <span class="p">),</span> <span class="s1">'Windows NT'</span> <span class="p">)</span> <span class="p">)</span> <span class="p">{</span></span>
<span id="LC7" class="line"> <span class="c1">// Windows</span></span>
<span id="LC8" class="line"> <span class="nv">$cmd</span> <span class="o">=</span> <span class="nb">shell_exec</span><span class="p">(</span> <span class="s1">'ping '</span> <span class="mf">.</span> <span class="nv">$target</span> <span class="p">);</span></span>
<span id="LC9" class="line"> <span class="p">}</span></span>
<span id="LC10" class="line"> <span class="k">else</span> <span class="p">{</span></span>
<span id="LC11" class="line"> <span class="c1">// *nix</span></span>
<span id="LC12" class="line"> <span class="nv">$cmd</span> <span class="o">=</span> <span class="nb">shell_exec</span><span class="p">(</span> <span class="s1">'ping -c 4 '</span> <span class="mf">.</span> <span class="nv">$target</span> <span class="p">);</span></span>
<span id="LC13" class="line"> <span class="p">}</span></span>
<span id="LC14" class="line"> <span class="c1">// Feedback for the end user</span></span>
<span id="LC15" class="line"> <span class="nv">$html</span> <span class="mf">.</span><span class="o">=</span> <span class="s2">"<pre></span><span class="si">{</span><span class="nv">$cmd</span><span class="si">}</span><span class="s2"></pre>"</span><span class="p">;</span></span>
<span id="LC16" class="line"><span class="p">}</span></span>
<span id="LC17" class="line"><span class="cp">?></span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<p>code review result:</p>
<div class="white"><div class="highlight markdown-code-block">
<pre><span id="LC1" class="line"><span class="o">================</span>Review <span class="nv">Summary</span><span class="o">====================</span></span>
<span id="LC2" class="line"></span>
<span id="LC3" class="line">Code review:</span>
<span id="LC4" class="line"></span>
<span id="LC5" class="line">1. Security: The code is vulnerable to <span class="nb">command </span>injection attacks as the user input is directly used <span class="k">in </span>the shell_exec<span class="o">()</span> <span class="k">function</span><span class="nb">.</span> An attacker can potentially execute malicious commands on the server by injecting them into the <span class="s1">'ip'</span> parameter.</span>
<span id="LC6" class="line">2. Error handling: There is no error handling <span class="k">in </span>the code. If the ping <span class="nb">command </span>fails, the error message is not displayed to the user.</span>
<span id="LC7" class="line">3. Input validation: There is no input validation <span class="k">for </span>the <span class="s1">'ip'</span> parameter. It should be validated to ensure that it is a valid IP address or domain name.</span>
<span id="LC8" class="line">4. Cross-platform issues: The code assumes that the server is either running Windows or <span class="k">*</span>nix operating systems. It may not work correctly on other platforms.</span>
<span id="LC9" class="line"></span>
<span id="LC10" class="line">Suggestions <span class="k">for </span>improvement:</span>
<span id="LC11" class="line"></span>
<span id="LC12" class="line">1. Use escapeshellarg<span class="o">()</span> <span class="k">function </span>to sanitize the user input before passing it to shell_exec<span class="o">()</span> <span class="k">function </span>to prevent <span class="nb">command </span>injection.</span>
<span id="LC13" class="line">2. Implement error handling to display error messages to the user <span class="k">if </span>the ping <span class="nb">command </span>fails.</span>
<span id="LC14" class="line">3. Use a regular expression to validate the <span class="s1">'ip'</span> parameter to ensure that it is a valid IP address or domain name.</span>
<span id="LC15" class="line">4. Use a more robust method to determine the operating system, such as the PHP_OS constant, which can detect a wider range of operating systems.</span>
<span id="LC16" class="line"></span>
<span id="LC17" class="line"><span class="o">==================================================</span></span></pre>
<div class="markdown-code-block-copy-btn"></div>
</div></div>
<h2>
<a id="user-content-star-history" class="anchor" href="#star-history"></a>Star History</h2>
<p><a href="https://gitee.com/link?target=https%3A%2F%2Fstar-history.com%2F%23appleboy%2Fcodegpt%26Date"><img src="https://api.star-history.com/svg?repos=appleboy/codegpt&type=Date" alt="Star History Chart"></a></p>
<h2>
<a id="user-content-reference" class="anchor" href="#reference"></a>Reference</h2>
<ul>
<li>
<a href="https://gitee.com/link?target=https%3A%2F%2Fplatform.openai.com%2Fdocs%2Fguides%2Fchat">OpenAI Chat completions documentation</a>.</li>
<li><a href="https://gitee.com/link?target=https%3A%2F%2Fopenai.com%2Fblog%2Fintroducing-chatgpt-and-whisper-apis">Introducing ChatGPT and Whisper APIs</a></li>
</ul></div>
</div>
<div class='file_line'></div>
<script>
window.Gitee.initReadmeCatalog();
toMathMlCode('','markdown-body');
$('.file_content a, .catalog-li a.anchor').click(function () {
var anchor = $(this).attr('href')
window.location.hash = anchor
})
</script>
</div>
</div>
<div class='tree_progress'></div>
<div class='ui small modal' id='modal-linejump'>
<div class='ui custom form content'>
<div class='field'>
<div class='ui right action input'>
<input placeholder='跳转至某一行...' type='number'>
<div class='ui orange button'>
跳转
</div>
</div>
</div>
</div>
</div>
<script>
"use strict";
$('.js-check-star').checkbox('set unchecked')
</script>
</div>
</div>
</div>
<div class='four wide column' style='display: none;'>
<script>
window.gon.projectRightSide = {
homepage: null,
description: "15mHCL python",
url: '/yangxl6/py-hcl-web/update_description',
i18n: {
invalidHomepage: '不是有效的 http 地址',
descriptionLimitExceeded: '简介长度不得超过%{limit}个字符',
noDescription: '暂无描述',
noPermission: '无权限操作!',
requestError: '修改发生错误,请稍后重试!'
}
}
window.gon.cloneArrSelectedLabel = [] || []
$(function () {
var $editModal = $('#edit-project-description')
$editModal.modal({
onShow: function () {
window.globalUtils.getFocus($editModal.find('textarea'))
}
})
$('.project__right-side').on('click', '.header .btn-edit', function () {
$editModal.modal('show')
})
$('#license-popup').popup({ position: 'bottom center', lastResort: 'bottom center' })
$('.js-project-label_show').projectLabel({
i18n: {
empty: "标签名不能为空",
verify: "标签名只允许包含中文、字母、数字或者中划线(-),不能以中划线开头,且长度少于35个字符",
max: "最多选择 5 个标签"
}
})
})
</script>
</div>
</div>
</div>
<script>
(function() {
$(function() {
Tree.init();
return TreeCommentActions.init();
});
}).call(this);
</script>
<script src="https://cn-assets.gitee.com/webpacks/gitee-linker.b5c93d77567006097fca.js"></script>
</div>
<script>
(function() {
var donateModal;
Gitee.modalHelper = new GiteeModalHelper({
alertText: '提示',
okText: '确定'
});
donateModal = new ProjectDonateModal({
el: '#project-donate-modal',
alipayUrl: '/yangxl6/py-hcl-web/alipay',
wepayUrl: '/yangxl6/py-hcl-web/wepay',
nameIsBlank: '名称不能为空',
nameTooLong: '名称过长(最多为 36 个字符)',
modalHelper: Gitee.modalHelper
});
if (null === 'true') {
donateModal.show();
}
$('#project-donate').on('click', function() {
return donateModal.show();
});
}).call(this);
</script>
<script>
Tree.initHighlightTheme('white')
</script>
</div>
<script>
$(function() {
GitLab.GfmAutoComplete.dataSource = "/yangxl6/py-hcl-web/autocomplete_sources"
GitLab.GfmAutoComplete.Emoji.assetBase = '/assets/emoji'
GitLab.GfmAutoComplete.setup();
});
</script>
<div class='ui container'>
</div>
<div class='bottombar'>
</div>
</footer>
<script>
var officialEmail = $('#git-footer-email').text()
$('#git-footer-main .icon-popup').popup({ position: 'bottom center' })
$('#git-footer-email').text(officialEmail.replace('#', '@'))
window.gon.popover_card_locale = {
follow:"关注",
unfollow:"已关注",
gvp_title: "GVP - Gitee 最有价值开源项目",
project: "项目",
org: "开源组织",
member: "",
author: "作者",
user_blocked: "该用户已被屏蔽或已注销",
net_error: "网络错误",
unknown_exception: "未知异常"
}
window.gon.select_message = {
placeholder: "请输入个人空间地址或完整的邮箱地址"
}
</script>
<script src="https://cn-assets.gitee.com/webpacks/popover_card-d30978018805efc377e9.bundle.js"></script>
<link rel="stylesheet" media="all" href="https://cn-assets.gitee.com/webpacks/css/gitee_nps-69491f94919350b0258c.css" />
<script src="https://cn-assets.gitee.com/webpacks/gitee_nps-548cf00696f895086765.bundle.js"></script>
<script src="https://cn-assets.gitee.com/webpacks/gitee_icons-3cce3cb0d49977ab50c9.bundle.js"></script>
<script>
var opt = { position: 'left center'};
var $helpSideToolbar = $('.button.toolbar-help');
var $toolbarRoll = $('.toolbar-roll');
$(function() {
if (true) {
$helpSideToolbar.popup(opt).popup({lastResort:'left center'})
} else {
$helpSideToolbar.popup({lastResort:'left center'}).popup('show', opt);
setTimeout(function() {
$helpSideToolbar.popup('hide', opt);
}, 3000);
}
if ($toolbarRoll.length) {
setInterval(function() {
var $nextActiveLink = $toolbarRoll.find('a.active').next();
if (!$nextActiveLink.length) {
$nextActiveLink = $toolbarRoll.find('a:first-child');
}
$nextActiveLink.attr('class', 'active').siblings().removeClass('active init');
}, 5000);
}
})
</script>
<style>
.side-toolbar .bdsharebuttonbox a {
font-size: 24px;
color: white !important;
opacity: 0.9;
margin: 6px 6px 0px 6px;
background-image: none;
text-indent: 0;
height: auto;
width: auto;
}
</style>
<style>
#udesk_btn a {
margin: 0px 20px 217px 0px !important;
}
#ent-sale-img-wrap {
margin: 0px 15px 294px 0px !important;
}
</style>
<script>
(function() {
$('#project-user-message').popup({
position: 'left center'
});
}).call(this);
</script>
<script>
Gitee.initSideToolbar({
hasComment: true,
commentUrl: '/yangxl6/py-hcl-web#tree_comm_title'
})
</script>
<link rel="stylesheet" media="all" href="https://cn-assets.gitee.com/webpacks/css/side_toolbar_feedback-5dcc1be9cca438cc952f.css" />
<script src="https://cn-assets.gitee.com/webpacks/side_toolbar_feedback-d4a5ed14973052816039.bundle.js"></script>
</body>
</html>