416 Commits

Author SHA1 Message Date
  choikeith 0f15a1b792 fix: pipeline and online inference entry 2 years ago
  chenyifan01 e80d4962e4 Merge pull request 'fix-3680 不再校验json验证码的长度' (#3763) from fix-3693 into V20230307 2 years ago
  ychao 6890224eff fix-3680 2 years ago
  chenyifan01 3ef1c30ed3 Merge pull request '#3631 处理csv文件不是4列的情况' (#3762) from fix-3631 into V20230307 2 years ago
  liuzx b407f1892b Merge branch 'V20230307' into fix-3631 2 years ago
  liuzx 8b811c9f8d #3631 处理csv文件不是4列的情况 2 years ago
  chenyifan01 eae0d152c2 Merge pull request 'fix-3693 3576' (#3761) from fix-3693 into V20230307 2 years ago
  ychao d2312f2320 去掉注释和多余的代码 2 years ago
  ychao 97a17c4a9a 检查环境镜像是否相同 2 years ago
  zhoupzh 89d72fabc8 complete npu select image 2 years ago
  zhoupzh f31f28a8a9 Merge pull request '#3754 【代码仓】新建文件、上传文件、文件历史按钮应显示在文件列表区' (#3755) from fix-csh into V20230307 2 years ago
  chenshihai a15e470116 #3754 2 years ago
  chenyifan01 788951f92e Merge pull request 'fix-3631' (#3752) from fix-3631 into V20230307 2 years ago
  liuzx cc803cc79e Merge branch 'V20230307' into fix-3631 2 years ago
  liuzx 63c5c9283d #3631 积分批量充值 2 years ago
  ychao 94c6f5669f 提交代码 2 years ago
  ychao ed8a85a1f1 Merge pull request '修复智算调试任务渲染错误页问题' (#3753) from gcu-bugfix into V20230307 2 years ago
  chenyifan01 1fece56ae7 fix bug 2 years ago
  liuzx ceb0c7f962 #3631 update 2 years ago
  liuzx d386007f71 #3631 2 years ago
  liuzx 4021e45af1 #3631 2 years ago
  liuzx a29d81b9d3 Merge branch 'fix-3631' of https://openi.pcl.ac.cn/OpenI/aiforge into fix-3631 2 years ago
  liuzx 6723238552 #3631 2 years ago
  liuzx 25fcb5e794 Merge branch 'V20230307' into fix-3631 2 years ago
  zouap a56275ca2a Merge pull request 'fix-3648' (#3751) from fix-3648 into V20230307 2 years ago
  liuzx 26d4eef2b7 Merge branch 'V20230307' into fix-3648 2 years ago
  zouap a4863fb666 Merge pull request '为实训平台接入提供智算网络调试api接口' (#3749) from mlops-debug into V20230307 2 years ago
  ychao 2c51e7c4cc 为实训平台接入提供智算网络调试api接口 2 years ago
  liuzx b14a711f7a fix-3631 2 years ago
  liuzx 5d0ccd50a4 积分奖励管理员功能 2 years ago
  liuzx c937bf8f0b fix-3631 2 years ago
  liuzx 4ad1f5e22e Merge branch 'fix-3631' of https://openi.pcl.ac.cn/OpenI/aiforge into fix-3631 2 years ago
  liuzx df2a2a871e 支持非utf-8格式的文件 2 years ago
  chenshihai 2c34e74122 Merge remote-tracking branch 'origin/V20230307' into fix-3631 2 years ago
  liuzx bf0dafb059 add batch_operate reward point 2 years ago
  liuzx 6f6968794c add batch_operate reward point 2 years ago
  liuzx eea7adba69 add batch reward point 2 years ago
  ychao 7d7e2620d5 Merge pull request 'V20230215.patch' (#3744) from V20230215.patch into V20230307 2 years ago
  chenyifan01 fb74f411e0 Merge pull request '修复模板消息只发送一次的问题' (#3743) from point-optimize-v1 into V20230307 2 years ago
  chenyifan01 cab8926b4b fix bug 2 years ago
  chenyifan01 b6de67218a Merge pull request 'point-optimize-v1' (#3741) from point-optimize-v1 into V20230307 2 years ago
  chenyifan01 36913dcf06 update 2 years ago
  chenyifan01 d1a3d29634 update 2 years ago
  chenyifan01 ede6b61bbf Merge pull request '微信模板消息添加日志' (#3740) from point-optimize-v1 into V20230307 2 years ago
  chenyifan01 00a472360c Merge branch 'V20230307' into point-optimize-v1 2 years ago
  chenyifan01 6f9664577e ad log 2 years ago
  liuzx 865050936a fix-3631 2 years ago
  zhoupzh 00966c33d8 Merge pull request '#3660 给仓库新建合并请求时连续点击多次“”创建合并请求“”按钮会创建多条重复的合并请求' (#3736) from fix-csh into V20230307 2 years ago
  chenshihai 95d8dcdb60 Merge branch 'V20230307' into fix-csh 2 years ago
  zhoupzh a138cc5c08 Merge pull request 'fix-wenxin' (#3735) from fix-wenxin into V20230215.patch 2 years ago
  zhoupzh e4e94fc54a Merge branch 'V20230215.patch' into fix-wenxin 2 years ago
  zhoupzh 291d465656 Merge branch 'fix-wenxin' of openi.pcl.ac.cn:OpenI/aiforge into fix-wenxin 2 years ago
  zhoupzh 27110d1867 fix issue 2 years ago
  zhoupzh 20fadb5c28 Merge pull request 'fix-wenxin' (#3734) from fix-wenxin into V20230215.patch 2 years ago
  zhoupzh 8bd4bb0e56 Merge branch 'V20230215.patch' into fix-wenxin 2 years ago
  zhoupzh 317ee6eae5 fix issue 2 years ago
  zhoupzh 021a049d4b Merge branch 'fix-wenxin' of openi.pcl.ac.cn:OpenI/aiforge into fix-wenxin 2 years ago
  zhoupzh e8c603c3f7 fix issue 2 years ago
  zhoupzh 744c64280a Merge pull request 'fix issue' (#3731) from fix-wenxin into V20230215.patch 2 years ago
  zhoupzh e7fcf5aab9 Merge branch 'V20230215.patch' into fix-wenxin 2 years ago
  zhoupzh 321eac7d02 fix issue 2 years ago
  zhoupzh 79f30d1c57 Merge pull request 'fix-wenxin' (#3730) from fix-wenxin into V20230215.patch 2 years ago
  zhoupzh fe422df301 Merge pull request 'fix issue' (#3729) from fix-wenxin into V20230307 2 years ago
  zhoupzh 3062bdb6a7 fix issue 2 years ago
  chenshihai 5ec2c9fff5 remove useless import 2 years ago
  chenshihai 881a1ef7f4 #3660 2 years ago
  ychao 8ae6b3d5b4 Merge pull request 'V20230215.patch' (#3727) from V20230215.patch into V20230307 2 years ago
  ychao b5bf08e0e2 Merge pull request '合入文心生图功能。' (#3725) from zouap into V20230215.patch 2 years ago
  zouap 3796605bbe Merge branch 'V20230215.patch' into zouap 2 years ago
  ychao ab23347f21 Merge pull request 'IDE bugfix' (#3724) from wangwei10061/aiforge:v20230215_ide_feature into V20230215.patch 2 years ago
  zouap 654318938a Merge remote-tracking branch 'origin/V20230215.patch' into zouap 2 years ago
  weishao 38ca9ef7b7 Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  weishao 2703fea7ae 无权限提示 2 years ago
  linlu b4761ed08d Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu 6c6d69af1c fix ide 重置所有提交bug 2 years ago
  zhoupzh 5dc8b3eae8 fix issue 2 years ago
  weishao ab6c5f810b 无权限提示 2 years ago
  ychao 27de3c892d Merge pull request 'V20230215' (#3723) from V20230215 into develop 2 years ago
  linlu c665c71e2b Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu 7f638f7b2e fix ide 重置所有提交bug 2 years ago
  ychao 6523ee03db Merge pull request 'IDE bugfix' (#3722) from wangwei10061/aiforge:v20230215_ide_feature into V20230215 2 years ago
  zouap 52ba0f619e 修正等待时间长度 2 years ago
  zouap d33821e984 提交代码,优化等待时间提法 2 years ago
  zouap c7e7c64212 提交代码,优化等待时间提法 2 years ago
  zouap 02845a0a6d 提交代码,优化提示信息 2 years ago
  zhoupzh d003fab865 Merge branch 'zouap' of openi.pcl.ac.cn:OpenI/aiforge into zouap 2 years ago
  zhoupzh 8d87ac8eca fix issue 2 years ago
  weishao ada1a0f639 IDE 文件树truncate及download失效问题修复 2 years ago
  zouap e01a2a3dec Merge pull request 'fix-3325' (#3721) from fix-3325 into V20230215 2 years ago
  zouap d60f2e2377 Merge branch 'V20230215' into fix-3325 2 years ago
  linlu f119a8762c Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  ychao 685f483375 更新 'README.md' 2 years ago
  ychao 49318eade3 更新 'README.md' 2 years ago
  ychao 784efbe3c7 增加linux开发环境快速搭建说明 2 years ago
  chenyifan01 0cddfe7529 Merge pull request '修改上线时扣分逻辑' (#3717) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 88677f446e Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 a242154406 update 2 years ago
  zouap 1263175a9b 支持文心多节点 2 years ago
  zouap d1cc3cd65d 支持文心多节点 2 years ago
  zouap 77137a85bb 提交代码,支持多节点部署推理 2 years ago
  chenyifan01 c873be8973 Merge pull request '积分消耗:添加扣分任务最小时间戳配置' (#3716) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 89e8c4a9c9 积分消耗:添加扣分任务最小时间戳配置 2 years ago
  ychao b110637246 Merge pull request '#3713及#3714问题解决' (#3715) from zouap_static into V20230215 2 years ago
  zouap a907ee1b2a Merge branch 'V20230215' into zouap_static 2 years ago
  zouap 8dc8444473 #3713及#3714问题解决 2 years ago
  zouap 79b797efe1 #3714 【安全评测】终态时详情页面运行时长显示00:00:00 2 years ago
  zouap dc97d77919 #3713 【安全评测】点击下载日志文件显示500 error页面 2 years ago
  zouap a0fe1032fa Merge remote-tracking branch 'origin/V20230215' into zouap 2 years ago
  chenshihai a1760ded33 Merge pull request '解决模型安全评测Testing状态显示问题' (#3712) from zouap_static into V20230215 2 years ago
  zouap 7648b600a4 Merge branch 'V20230215' into zouap_static 2 years ago
  chenshihai 4a67f8dd1d fix modelsafety detail status icon 2 years ago
  chenshihai c0a80c7dad Merge pull request 'IDE代码优化' (#3710) from wangwei10061/aiforge:v20230215_ide_feature into V20230215 2 years ago
  zouap 86b480fe30 提交模型安全评测的图标 2 years ago
  weishao 53e0f114ed conflict fix 2 years ago
  linlu afc0f970c9 Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu b427761c42 package remove uglifyjs 2 years ago
  weishao 53cded49d3 Revert "tmp" 2 years ago
  zhoupzh f5590806d5 Merge pull request '模型安全评测的详情页面Testing状态增加图标合入' (#3709) from zouap_static into V20230215 2 years ago
  zouap 71d62173e5 Merge branch 'V20230215' into zouap_static 2 years ago
  zouap f0a6fc77d2 模型安全评测的结果提交 2 years ago
  weishao 6792b76d6c ide无后缀文件处理 2 years ago
  chenyifan01 6b7596bdab Merge pull request '修复徽章bug' (#3708) from fix-3330 into V20230215 2 years ago
  chenyifan01 6daea88e7e Merge remote-tracking branch 'origin/fix-3330' into fix-3330 2 years ago
  chenyifan01 72df3a3bd5 fix bug 2 years ago
  zouap 98ed29055d Merge remote-tracking branch 'origin/V20230215' into zouap 2 years ago
  zhoupzh e73ee27f68 Merge pull request '修正Testing图标。遗漏了详情页面。' (#3706) from zouap_static into V20230215 2 years ago
  zouap 176ad7328a Merge branch 'V20230215' into zouap_static 2 years ago
  zouap 027ea9a30d Merge branch 'zouap_static' of https://git.openi.org.cn/OpenI/aiforge into zouap_static 2 years ago
  zouap 61c680c608 修改Testing图标 2 years ago
  linlu 3abd97738b remove UglifyJsPlugin 2 years ago
  ychao a729ecb892 Merge pull request '修改模型地址获取变量,解决模型评测问题' (#3705) from zouap_static into V20230215 2 years ago
  zouap 2d76583d60 Merge branch 'V20230215' into zouap_static 2 years ago
  zouap e4bf62d51a 修改模型地址获取变量,解决模型评测问题 2 years ago
  linlu d995438724 webpack UglifyJsPlugin 2 years ago
  linlu 9f065c4034 add UglifyJsPlugin 2 years ago
  weishao cfebea5971 Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  weishao 39a1f13f68 tmp 3 years ago
  linlu 102d977e52 ide删除console,代码撤回提交记录存在 2 years ago
  chenyifan01 f216d62e0d Merge pull request '修改微信通知内容' (#3703) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 1a4015488e 修改微信通知内容 2 years ago
  zhoupzh 8c9e5005af Merge pull request '#3088 【模型安全评测】testing状态增加图标显示' (#3702) from zouap_static into V20230215 2 years ago
  zouap acd05507d5 Merge branch 'V20230215' into zouap_static 2 years ago
  zouap 87cc1a4b6e #3088 【模型安全评测】testing状态增加图标显示 2 years ago
  zouap 50a69b59a4 提交代码,增加文本缓存 2 years ago
  zouap 4a42cb3423 Merge remote-tracking branch 'origin/V20230215' into zouap 2 years ago
  zouap ef678b1abc Merge pull request '优化前端构建' (#3700) from fix-csh into V20230215 2 years ago
  chenshihai 185049d185 Merge branch 'V20230215' into fix-csh 2 years ago
  chenshihai 80670d1dc9 update package.json 2 years ago
  chenshihai 20715da3d0 update webpack config 2 years ago
  chenshihai 0f5b2ca5c8 update Makefile 2 years ago
  chenyifan01 490f5699d3 Merge pull request '修复智算训练任务结束时状态问题' (#3699) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 d152c4d982 Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 fae92001af fix bug 2 years ago
  zouap 7562d247ab 解决合并冲突 2 years ago
  ychao fb142ba36a Merge pull request '代码仓库增加轻量级编辑器WebIDE' (#3695) from wangwei10061/aiforge:v20230215_ide_feature into V20230215 2 years ago
  ychao b2ecaf0493 Merge pull request '修正查询训练任务模型结果的API接口' (#3696) from zouap_static into V20230215 2 years ago
  zouap 059dc17e6c Merge branch 'V20230215' into zouap_static 2 years ago
  zouap d884e20887 修正查询训练任务模型结果的API接口 2 years ago
  weishao 1e47feb2b9 merge ide 2 years ago
  zouap 8dc7df1f53 提交代码,解决获取训练模型API接口问题 2 years ago
  linlu cd22b4be2c add ide loading 2 years ago
  linlu 921818ec2c Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu d917ee8e97 ide修改文案 2 years ago
  zouap 8e601f4fa0 Merge branch 'zouap' of https://git.openi.org.cn/OpenI/aiforge into zouap 2 years ago
  zouap 00884497c9 增加百度限流后重试 2 years ago
  weishao 543314e66f Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu 4a9fcc9598 add yarn.lock 2 years ago
  linlu 2d661648ff Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu 8364c04ed6 ide issue 16 17 18 2 years ago
  chenyifan01 03d05cfcdb Merge pull request '积分微信通知:修改模板' (#3692) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 902a9f87a7 积分微信通知:修改模板 2 years ago
  weishao fa5720747b Revert "tmp" 3 years ago
  zhoupzh 68c41bc115 fix issue 2 years ago
  chenshihai 4d2cc10f4f Merge pull request 'fix issue' (#3691) from fix-2351 into V20230215 2 years ago
  zhoupzh 9c7d54cf26 Merge branch 'V20230215' into fix-2351 2 years ago
  zhoupzh eeb91308e2 fix issue 2 years ago
  zhoupzh e1de5dc80e fix issue 2 years ago
  zhoupzh 17d0c2c6d9 fix issue 2 years ago
  zhoupzh c9aac74514 fix issue 2 years ago
  zhoupzh c14fa9bac7 Merge branch 'zouap' of openi.pcl.ac.cn:OpenI/aiforge into zouap 2 years ago
  zhoupzh d440e8abee fix issue 2 years ago
  zhoupzh 72fd11b929 Merge pull request '#3687 首页banner功能优化' (#3690) from fix-csh into V20230215 2 years ago
  zouap eaeb2092b7 提交代码,解决关键字包括敏感字 2 years ago
  zouap 8b31d5c85b 将文字审核放入到队列中。 2 years ago
  chenshihai af1828aa51 Merge remote-tracking branch 'origin/V20230215' into fix-csh 2 years ago
  chenshihai 554750482a #3687 update home page banner 2 years ago
  chenshihai 63048c33bf remove useless import 2 years ago
  chenyifan01 18a2a07db1 Merge pull request '命令修改' (#3688) from fix-3325 into V20230215 2 years ago
  ychao 3acb30165f 命令修改 2 years ago
  youys 6f7e2f2b29 Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  youys b1692001a2 修复bug 1.web ide文件排序 2 years ago
  linlu 0bb50c0736 ide支持顶层结构添加目录 2 years ago
  zhoupzh b2a6b1e388 fix issue 2 years ago
  zouap 7b9b874e19 增加查询文心生图的接口。 2 years ago
  zouap 24a583dd9b 增加返回等待时间接口 2 years ago
  zouap fef8ccd9fe 提交代码,增加节点数配置 2 years ago
  zouap 5e4cd568fd 消费者初始化 2 years ago
  zouap a714df12bb 协程增加打印 2 years ago
  zouap ccf29ba1e2 提交代码。 2 years ago
  zouap 6727a2951e Merge branch 'zouap' of https://git.openi.org.cn/OpenI/aiforge into zouap 2 years ago
  zouap 91661a1481 增加文心生成图的队列处理 2 years ago
  chenyifan01 d5015ab54c Merge pull request '徽章改为用户id' (#3685) from fix-3330 into V20230215 2 years ago
  chenyifan01 4461b3aa80 Merge branch 'V20230215' into fix-3330 2 years ago
  chenyifan01 b0ab36a40f Merge remote-tracking branch 'origin/V20230215' into fix-3330 2 years ago
  zhoupzh 953386c9fd fix issue 2 years ago
  zouap eb15f0d7ce Merge remote-tracking branch 'origin/V20230215' into zouap 2 years ago
  chenyifan01 b402d52c58 Merge pull request '修复积分bug' (#3677) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 096681677d Merge branch 'V20230215' into point-optimize-v1 2 years ago
  chenyifan01 4111a065f5 fix bug 2 years ago
  zouap 7a53959fea Base64转换码 2 years ago
  linlu d423746fbe Merge branch 'v20230215_ide_feature' of https://git.pcl.ac.cn/wangwei10061/aiforge into v20230215_ide_feature 2 years ago
  linlu 48cac869ef fix git 文件历史按钮右对齐 2 years ago
  youys 788561e490 处理带特殊字符串的分支名 2 years ago
  zouap 1b45152e7f Merge branch 'zouap' of https://git.openi.org.cn/OpenI/aiforge into zouap 2 years ago
  zouap 532e32e287 提交代码,去掉图片审核 2 years ago
  zhoupzh cbaed5d343 Merge branch 'zouap' of openi.pcl.ac.cn:OpenI/aiforge into zouap 2 years ago
  zhoupzh 89af189db5 fix issue 2 years ago
  zouap e6c89e5b31 提交代码。 2 years ago
  zouap cb16d4dd10 提交代码。 2 years ago
  linlu 9cf66422e7 ide branch delete decode base64 2 years ago
  youys 8c6937f993 merge 2 years ago
  youys d2ed447551 web ide url上的分支参数base64编码 2 years ago
  linlu 18904ce733 fix ide brach base64 2 years ago
  zouap ef196844bd Merge branch 'zouap' of https://git.openi.org.cn/OpenI/aiforge into zouap 2 years ago
  zouap 1d02dfdba6 解决冲突 2 years ago
  zhoupzh a76dba03f0 Merge branch 'zouap' of openi.pcl.ac.cn:OpenI/aiforge into zouap 2 years ago
  zhoupzh 9e7e6940a9 fix issue 2 years ago
  zouap 57d2eabca5 增加文字及图片过滤 2 years ago
  linlu 35f327dd37 调整webide大小 2 years ago
  zhoupzh e1cbd03e94 Merge pull request '#3674 【积分消耗】消耗明细的评测任务名称点击后应打开任务详情页' (#3675) from fix-csh into V20230215 2 years ago
  chenshihai 4e247e37b6 #3674 【积分消耗】消耗明细的评测任务名称点击后应打开任务详情页 2 years ago
  linlu 6c1fb34b9b git仓库代码首页宽度调整 2 years ago
  zouap b9dd08986b Merge pull request '修改国际化信息' (#3670) from fix-3325 into V20230215 2 years ago
  zouap b0dde87634 Merge branch 'V20230215' into fix-3325 2 years ago
  ychao d4d12641e9 去掉用于联调的错误信息重定向 2 years ago
  ychao 3b5aeb1546 修改国际化信息 2 years ago
  linlu 9d13e3c23d fix ide 克隆下载代码css 2 years ago
  linlu c1ad6d31ff 固定克隆输入框宽度 2 years ago
  linlu 145a0b1d8f fix ide bug 2 years ago
  linlu 2a1e2e01bd fix ide bug 2 years ago
  linlu 5f922359aa fix ide bug 2 years ago
  chenyifan01 558efaba52 Merge pull request '积分相关修改' (#3668) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 e3729902a8 fix 2 years ago
  chenyifan01 54d124b529 Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 bc90055648 修改云脑状态同步间隔 2 years ago
  zouap b9790200f1 Merge pull request 'V20221228.patch(科技项目2030)' (#3651) from V20221228.patch into V20230215 2 years ago
  ychao c319f4bf22 Merge branch 'V20230215' into V20221228.patch 2 years ago
  zouap 01133dfd4a Merge remote-tracking branch 'origin/V20230215' into zouap_static 2 years ago
  weishao 3b9a289490 Merge branch 'feature_ide_20221214' into v20230215_ide_feature 2 years ago
  zouap 6235626ded 解决模型冲突问题 2 years ago
  youys 22ef7bd374 提交代码新增一次提交方法 2 years ago
  zouap 8c709460db Merge remote-tracking branch 'origin/V20230215' into zouap 2 years ago
  zouap 9264064d72 Merge pull request 'fix-3377' (#3666) from fix-3325 into V20230215 2 years ago
  linlu 5aab5df485 fix ide bug 2 years ago
  ychao 90df573a98 Merge branch 'V20230215' into fix-3325 2 years ago
  ychao 6271e2a631 国际化信息 2 years ago
  linlu fc12d4b36a ide删除console 2 years ago
  chenyifan01 9f9bbca2a7 #3664 2 years ago
  ychao d27f01f42f 标注错误输出 2 years ago
  chenyifan01 71e01767e9 Merge pull request '修复积分余额不足时云脑二推理任务不能停止的问题' (#3662) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 5b5edd5e92 Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 4476ef007a Merge remote-tracking branch 'origin/point-optimize-v1' into point-optimize-v1 2 years ago
  chenyifan01 f9d927fc5d fix bug 2 years ago
  zhoupzh 4e3fa713c8 fix issue 2 years ago
  ychao db2b8b6028 提交代码 2 years ago
  chenyifan01 e0bdee110a Merge pull request '#3630' (#3661) from point-optimize-v1 into V20230215 2 years ago
  chenyifan01 30fe85f42e Merge branch 'V20230215' into point-optimize-v1 2 years ago
  chenyifan01 f5659eb47f Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 c8d55e2558 Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 288517cada #3630 2 years ago
  zhoupzh 200d186951 clear console 2 years ago
  zhoupzh 56f2b03d9c 新增SIM2BRAIN_SNN任务类型 2 years ago
  zhoupzh 2e77d97941 新增SIM2BRAIN_SNN任务类型 2 years ago
  ychao c6686c7f64 Merge pull request 'update title' (#3658) from 2023 into V20221228.patch 2 years ago
  zhoupzh 2f3d2d61af 完善文心前后端联调 2 years ago
  weishao e03474dcfb merge ide 2 years ago
  liuzx 9d925c6a45 fix-3648 2 years ago
  chenshihai f48b29b999 Merge branch 'V20221228.patch' into 2023 2 years ago
  youys 297c2b5c8e ide commit 权限问题 2 years ago
  chenshihai 65d214a24b update title 2 years ago
  chenyifan01 3e3d5a0db8 Merge remote-tracking branch 'origin/V20230215' into fix-3330 2 years ago
  chenyifan01 77d772fc1a Merge pull request 'fix-3630' (#3657) from fix-3630 into V20230215 2 years ago
  chenyifan01 d906da84d0 Merge branch 'V20230215' into fix-3630 2 years ago
  chenyifan01 7720bdf027 Merge remote-tracking branch 'origin/fix-3630' into fix-3630 2 years ago
  chenyifan01 134224a3da #3630 2 years ago
  chenyifan01 ff109ccea7 Merge pull request '修复issue:【积分消耗】云脑1任务的succeeded终态不应被改写为stopped' (#3655) from point-optimize-v1 into V20230215 2 years ago
  zhoupzh 69d1f332e7 Merge branch 'zouap' of openi.pcl.ac.cn:OpenI/aiforge into zouap 2 years ago
  zhoupzh e6dc9c1372 ERNIE-ViLG AI 2 years ago
  chenyifan01 a0fbdf6887 Merge remote-tracking branch 'origin/V20230215' into point-optimize-v1 2 years ago
  chenyifan01 8270b04b18 Merge pull request '积分余额不足时微信通知用户' (#3650) from fix-3630 into V20230215 2 years ago
  chenyifan01 1288f24940 Merge branch 'V20230215' into fix-3630 2 years ago
  chenyifan01 3d9545ed70 #3653 2 years ago
  zouap 6c64657e32 增加Testing过程图标 2 years ago
  linlu 66b1307431 fix ide bug 2 years ago
  zouap 2a6e6556af 提交代码,接口问题 2 years ago
  zouap 598fd378e3 接口调用修改 2 years ago
  chenyifan01 c432952389 Merge branch 'V20230215' of https://git.openi.org.cn/OpenI/aiforge into V20230215 2 years ago
  zouap 970fea9805 接口调试更新 2 years ago
  zouap a673a5a9f9 提交文心作图的模型接口 2 years ago
  weishao 30b23281af Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 2 years ago
  linlu 2fc6172c72 ide button响应区调整 2 years ago
  zouap cddb4769c3 Merge pull request 'fix-3358' (#3652) from fix-3358 into V20230215 2 years ago
  liuzx 2a5e109e99 Merge branch 'V20230215' into fix-3358 2 years ago
  weishao 6ed8c88024 Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 2 years ago
  youys a989e6f52e Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 2 years ago
  youys 5b154e05d7 web ide按钮权限判断 2 years ago
  weishao 705ea9719d Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 2 years ago
  linlu 6ab0958ead ide paste 2 years ago
  chenyifan01 c1a9d88e99 #3630 2 years ago
  weishao 20b09f1995 权限错误调整 2 years ago
  liuzx 772b68ed1c fix-3358 2 years ago
  zouap 3f7fa11c16 Merge pull request 'fix-3534' (#3595) from fix-3534 into V20230215 2 years ago
  liuzx 962668b9fb Merge branch 'V20230215' into fix-3534 2 years ago
  zouap c8aa2b3ee5 Merge pull request 'fix-3578' (#3596) from fix-3578 into V20230215 2 years ago
  weishao e23f364df8 conflict fix 2 years ago
  ychao ecc23db835 修复配置方式 2 years ago
  liuzx daa43ab528 Merge branch 'V20230215' into fix-3534 2 years ago
  liuzx b211bc8e61 Merge branch 'V20230215' into fix-3578 2 years ago
  chenyifan01 b4ea5af91b #3630 2 years ago
  ychao 0f8d14febe Merge pull request 'merge V20230215' (#3635) from choi/aiforge:V20221228 into V20230215 2 years ago
  weishao 20eebb1c30 Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 2 years ago
  ychao 08ef00b5f7 新增评测类型 2 years ago
  zouap 2563600691 文心作画功能后端接口提交 2 years ago
  ychao 23ce904aed Merge pull request 'update avatar' (#3645) from 2023 into V20221228.patch 2 years ago
  chenshihai c7df914016 Merge branch '2023' of openi.pcl.ac.cn:OpenI/aiforge into 2023 2 years ago
  chenshihai edd2325378 update avatar 2 years ago
  ychao 4f5d96f736 Merge pull request 'reset logo' (#3643) from 2023 into V20221228.patch 2 years ago
  chenshihai 24ad216e86 reset logo 2 years ago
  linlu f9895b1b76 fix ide 70993 2 years ago
  ychao 0ce601cc72 Merge pull request '2023' (#3634) from 2023 into V20221228.patch 2 years ago
  ychao 3739673e74 修复bug 2 years ago
  chenshihai d84d1944ae update style 2 years ago
  chenyifan01 c2c9e8728b Merge pull request '2023-tech' (#3601) from 2023 into V20221228.patch 2 years ago
  chenyifan01 9e7772f7c0 Merge branch 'V20221228.patch' into 2023 2 years ago
  chenyifan01 5abfdfabf3 #3330 2 years ago
  chenshihai 41a0c3b076 科技项目 2 years ago
  linlu 27393b4e85 fix ide bug 2 years ago
  weishao c02052748f IDE merge 最新分支 2 years ago
  chenyifan01 a32141ad89 #3330 2 years ago
  chenyifan01 ea319f06c2 2030项目:启智项目兼容.git地址 2 years ago
  chenshihai b703d26f6c #3612 2 years ago
  liuzx f21c89ab55 fix-3578 2 years ago
  ychao e25a1e2a64 提交代码 2 years ago
  chenshihai ebbfaabbad 科技项目 2 years ago
  chenyifan01 6a1d3e2b3c update 2 years ago
  liuzx 0c12e91b3c fix-3578 2 years ago
  chenyifan01 3c125805db 修改非启智项目的标签逻辑 2 years ago
  chenshihai 56510bc84a 科技项目 2 years ago
  chenshihai adf8500563 科技项目 2 years ago
  chenshihai 1b648b7768 科技项目开发对接 2 years ago
  ychao 632a7e0835 提交代码 2 years ago
  ychao 59d2cc6ec7 提交代码 2 years ago
  ychao 5ebfd6e22f 提交代码 2 years ago
  ychao eb48f57e6c 提交代码 2 years ago
  liuzx 986e6687e5 fix-3578 2 years ago
  ychao 531066b1d4 提交代码 2 years ago
  chenshihai e201f957e0 科技项目开发对接 2 years ago
  chenyifan01 6a447daef3 添加用户角色管理 2 years ago
  chenyifan01 c397f131f5 添加用户角色管理 2 years ago
  liuzx 31173439e8 Merge branch 'V20230215' into fix-3534 2 years ago
  liuzx 4802185cc1 Merge branch 'V20230215' into fix-3578 2 years ago
  chenyifan01 4ac1523b7a 添加用户角色管理 2 years ago
  chenyifan01 ab0968bef9 添加用户角色管理 2 years ago
  chenyifan01 0b7bcd71fc 添加用户角色管理 2 years ago
  ychao 2f1912c1d2 提交代码 2 years ago
  ychao a9db0f6725 提交代码 2 years ago
  chenyifan01 ea59e675ea 新建非启智项目申请页面项目路径可选的用户和组织 2 years ago
  ychao abc908326f 提交代码 2 years ago
  chenshihai a071f308a7 科技项目开发 2 years ago
  liuzx db10194947 fix-3578 2 years ago
  chenyifan01 dd6d1dbf0f 新建非启智项目申请页面提交02 2 years ago
  ychao 0b641ea6d6 提交代码 2 years ago
  ychao 5bc84c6bd7 提交代码 2 years ago
  ychao 6ca271f30c 增加路由 2 years ago
  liuzx 15aadc3193 fix-3578 2 years ago
  chenyifan01 006f99a8f2 新建非启智项目申请页面提交01 2 years ago
  chenyifan01 73c4d22fdd 新建启智项目申请页面提交 2 years ago
  chenyifan01 8dda4d13e6 新建申请页面科技项目查询接口 2 years ago
  ychao 599e5d56be 提交代码 2 years ago
  ychao ceb83ab06d 提交代码 2 years ago
  ychao cc48ca8ec1 提交代码 2 years ago
  ychao 9db1328f27 自动建表 2 years ago
  ychao 652a0065d9 表结构字段名更新 2 years ago
  ychao ba61157bf2 提交代码 2 years ago
  zouap 2d116d67c7 修正SQL注入的查询问题 2 years ago
  liuzx 785f1020d5 fix-3534 2 years ago
  linlu 2f7a998349 ide monaco 2 years ago
  linlu 72d37cd2d0 ide editor 2 years ago
  youys 8d3be5543a 前端错误消息提示 2 years ago
  youys 2a75c6e16b web ide修改增加权限判断、错误信息返回 2 years ago
  weishao 601ed8a454 Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 3 years ago
  weishao d4292afab3 注释mock和oss,记得上线删除 3 years ago
  linlu d61c2717f7 Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 3 years ago
  linlu 0ad0063bff fix ide 3 years ago
  weishao f39a067ded 取分支代码 3 years ago
  weishao 8e0d5b0ce7 merge 3 years ago
  weishao eff33fe397 IDE 增加分支,未完成 3 years ago
  linlu 48e75ae9be fix ide 3 years ago
  linlu d214abc864 Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 3 years ago
  linlu b62c8de63a ide增加分支 3 years ago
  youys 5242d6091c Web IDE按钮,不是管理员或所有者不展示 3 years ago
  youys f3ecb8d715 webide-提交可选分支 3 years ago
  linlu f303b7ad6a Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 3 years ago
  linlu 07314c95ef ctrl+s 3 years ago
  weishao b8cd291ff7 Merge branch 'V20221214' into feature_ide_20221214 3 years ago
  weishao 44e34c5c24 Revert "tmp" 3 years ago
  linlu 593e74d851 ide fix 3 years ago
  linlu de54e0673f ide support jupyter 3 years ago
  linlu d44f6eebdc ide bug fix 3 years ago
  linlu 138fd1bb69 fix ide 3 years ago
  weishao 131891a630 tmp 3 years ago
  linlu 51e766bb02 fix ide 3 years ago
  linlu 31297d3fee ide 3 years ago
  linlu 54a8f35f8f Merge branch 'feature_ide_20221214' of https://git.pcl.ac.cn/wangwei10061/aiforge into feature_ide_20221214 3 years ago
  weishao 4727483dbe webIDE 3 years ago
  weishao b44a7334d2 webIDE 3 years ago
100 changed files with 25198 additions and 391 deletions
Split View
  1. +0
    -1
      .gitignore
  2. +1
    -1
      Makefile
  3. +199
    -10
      README.md
  4. +13
    -0
      assets/abandon.svg
  5. +11
    -0
      assets/code1.svg
  6. +11
    -0
      assets/code2.svg
  7. +13
    -0
      assets/codeLog.svg
  8. +11
    -0
      assets/drag.svg
  9. BIN
      assets/drag2.png
  10. +9
    -0
      assets/more.svg
  11. +11
    -0
      assets/submit.svg
  12. +13
    -0
      assets/submit2.svg
  13. +11
    -0
      assets/warehouse.svg
  14. +0
    -45
      custom/public/img/logo-w-origin.svg
  15. +45
    -1
      custom/public/img/logo-w.svg
  16. BIN
      go_build_code_gitea_io_gitea
  17. +109
    -47
      models/cloudbrain.go
  18. +31
    -47
      models/cloudbrain_static.go
  19. +14
    -0
      models/error.go
  20. +66
    -0
      models/modelapp.go
  21. +4
    -0
      models/models.go
  22. +4
    -4
      models/point_account.go
  23. +1
    -0
      models/repo.go
  24. +30
    -0
      models/repo_list.go
  25. +17
    -0
      models/reward_admin_log.go
  26. +73
    -0
      models/role.go
  27. +661
    -0
      models/tech_converge_info.go
  28. +2
    -2
      modules/auth/user_form.go
  29. +6
    -1
      modules/auth/wechat/cloudbrain.go
  30. +48
    -0
      modules/auth/wechat/point.go
  31. +11
    -6
      modules/auth/wechat/template.go
  32. +217
    -0
      modules/base/tool.go
  33. +2
    -6
      modules/cloudbrain/cloudbrain.go
  34. +1
    -1
      modules/cron/tasks_basic.go
  35. +80
    -0
      modules/modelappservice/modelsevice.go
  36. +1
    -1
      modules/modelarts/modelarts.go
  37. +5
    -0
      modules/modelarts/resty.go
  38. +231
    -0
      modules/modelarts/wenxinresty.go
  39. +2
    -0
      modules/notification/base/notifier.go
  40. +5
    -0
      modules/notification/base/null.go
  41. +8
    -0
      modules/notification/notification.go
  42. +7
    -0
      modules/notification/wechat/wechat.go
  43. +4
    -0
      modules/redis/redis_key/reward_redis_key.go
  44. +33
    -8
      modules/repofiles/content.go
  45. +6
    -2
      modules/repofiles/tree.go
  46. +411
    -0
      modules/repofiles/update.go
  47. +61
    -8
      modules/setting/setting.go
  48. +1
    -5
      modules/storage/storage.go
  49. +17
    -0
      modules/structs/cloudbrain.go
  50. +28
    -0
      modules/structs/repo_file.go
  51. +18
    -0
      modules/structs/repo_tree.go
  52. +18
    -0
      modules/structs/tech.go
  53. +2
    -1
      modules/templates/helper.go
  54. +22
    -0
      options/locale/locale_en-US.ini
  55. +24
    -0
      options/locale/locale_zh-CN.ini
  56. +22281
    -172
      package-lock.json
  57. +7
    -1
      package.json
  58. BIN
      public/0acc017d3b9b32f1f61a9af2315d5187.png
  59. BIN
      public/0f1600ced2415ea9530a1a55ec045fef.png
  60. BIN
      public/1f2e7b26b1be5e67e613178f38625008.png
  61. BIN
      public/276e9642cca7e5f8958c004269a6c0d7.png
  62. BIN
      public/41fa1ffe704082c381ae88ea686c9f39.png
  63. BIN
      public/5920c99e273bded4a2c702d4a1ed59ee.png
  64. BIN
      public/6f562e238482d4479212cbf367f6a293.png
  65. BIN
      public/71261d74041a4133ae4b9908d4a8109f.png
  66. BIN
      public/d4f9fbedc79f92e41f984283b6227127.png
  67. +93
    -21
      public/home/home.js
  68. +21
    -0
      public/html/js/nbview/LICENSE.txt
  69. +22
    -0
      public/html/js/nbview/Makefile
  70. +25
    -0
      public/html/js/nbview/README.md
  71. +35
    -0
      public/html/js/nbview/css/nbpreview.css
  72. +85
    -0
      public/html/js/nbview/css/notebook.css
  73. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_AMS-Regular.ttf
  74. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_AMS-Regular.woff
  75. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_AMS-Regular.woff2
  76. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Bold.ttf
  77. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Bold.woff
  78. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Bold.woff2
  79. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Regular.ttf
  80. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Regular.woff
  81. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Regular.woff2
  82. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Bold.ttf
  83. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Bold.woff
  84. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Bold.woff2
  85. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Regular.ttf
  86. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Regular.woff
  87. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Regular.woff2
  88. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Bold.ttf
  89. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Bold.woff
  90. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Bold.woff2
  91. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-BoldItalic.ttf
  92. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-BoldItalic.woff
  93. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-BoldItalic.woff2
  94. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Italic.ttf
  95. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Italic.woff
  96. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Italic.woff2
  97. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Regular.ttf
  98. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Regular.woff
  99. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Regular.woff2
  100. BIN
      public/html/js/nbview/css/vendor/fonts/KaTeX_Math-BoldItalic.ttf

+ 0
- 1
.gitignore View File

@@ -77,7 +77,6 @@ coverage.all
/integrations/pgsql.ini
/integrations/mssql.ini
/node_modules
/yarn.lock
/public/js
/public/css
/public/fonts


+ 1
- 1
Makefile View File

@@ -614,7 +614,7 @@ webpack_end:

$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules
rm -rf $(WEBPACK_DEST_DIRS)
npx webpack --hide-modules --display-entrypoints=false
npx webpack --hide-modules --display-entrypoints=false --progress
@touch $(WEBPACK_DEST)

.PHONY: update-translations


+ 199
- 10
README.md View File

@@ -5,7 +5,6 @@
[![release](https://img.shields.io/badge/release-1.21.11.1-blue)](https://openi.pcl.ac.cn/OpenI/aiforge/releases/latest)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)


## AiForge

启智AI开发协作平台是一个在线Web应用,旨在为人工智能算法、模型开发提供在线协同工作环境,它提供了<b>代码托管、数据集管理与共享、免费云端算力资源支持(GPU/NPU)、共享镜像</b>等功能。
@@ -15,43 +14,233 @@
本项目是基于[Gitea](https://github.com/go-gitea/gitea)发展而来的,我们对其进行了Fork并基于此扩展了人工智能开发中需要的功能,如数据集管理和模型训练等。对于和代码托管相关的功能,您可以参考[Gitea的文档](https://docs.gitea.io/zh-cn/)。

### 系统总体架构

下图展示了系统总体架构,本项目分为Web前端和服务后端,Web页面面向算法开发者、应用开发者、科研工作者、学生等用户群体,通过统一的Web页面入口,使用系统提供的系统服务。

后端服务涵盖了AI模型开发流水线,包括代码协同开发、数据管理、模型调试、训练、推理和部署等(*目前尚未支持模型部署*)。在不同的开发阶段,我们还将提供丰富的开发工具供用户使用,如数据标注、数据筛选、模型转换、模型压缩、代码检测等。我们也欢迎社区提供更多丰富的工具接入,提高利用平台进行开发的效率。
![系统架构图](assets/架构图.png)

## 在线服务使用

本项目的在线服务平台的详细使用帮助文档,可参阅本项目[百科](https://openi.pcl.ac.cn/OpenI/aiforge/wiki)内容。

- 如何创建账号

- 如何创建组织及管理成员权限

- 如何创建项目仓库

- 如何使用数据集功能

- 如何使用计算资源进行模型调试和训练

- 使用小技巧

- 常见问题(FAQ)
## 安装
您也可以基于本项目代码,在本地环境安装部署服务。
### 数据库准备
[数据库准备说明](https://docs.gitea.io/zh-cn/database-prep/)
### 从源代码安装
## 安装
您也可以基于本项目代码,在本地环境安装部署服务。
### 数据库准备
[数据库准备说明](https://docs.gitea.io/zh-cn/database-prep/)
### 从源代码安装

- node版本 >= v10.13.0

- golang版本 >= 1.13.3

[从源代码安装说明](https://docs.gitea.io/zh-cn/install-from-source/)

## 开发者指南

#### Linux下通过Docker快速搭建开发环境:

前提条件:已安装Docker,了解Docker的基本操作;熟悉git的基本操作(拉取代码,提交代码,合并代码,创建分支)。

1. 拉取镜像:
aiforge-postgres是数据库镜像,初始化了数据库;
aiforge-dev是开发环境镜像,安装了go,nodejs,openssh等依赖。
如果执行命令提示没有权限,在命令前加sudo
```
docker pull swr.cn-north-4.myhuaweicloud.com/openi/aiforge-postgres:v1
docker pull swr.cn-north-4.myhuaweicloud.com/openi/aiforge-dev:v1
```

2. 启动镜像:
注意:由于linux下的回车符和windows不一致,直接拷贝命令执行可能失败。 如果失败:去掉'\\',把命令改成一行命令再执行。
```
docker run --name postgres-openi \
-e POSTGRES_PASSWORD=openi \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-p 5432:5432 \
-v /home/openi/postgresql/data:/var/lib/postgresql/data \
-d swr.cn-north-4.myhuaweicloud.com/openi/aiforge-postgres:v1
```
```
docker run --name aiforgedev \
-p 8787:3000 \
-p 2222:22 \
-v /home/openi/data:/data \
-d swr.cn-north-4.myhuaweicloud.com/openi/aiforge-dev:v1
```

3. 进入开发容器并下载代码:
- 执行sudo docker ps,找到名称为aiforgedev的容器id(CONTAINER ID )
- 执行docker exec -it {开发容器id} /bin/bash
- 执行cd /data
- 执行git clone {aiforge项目地址或派生项目地址,例如https://openi.pcl.ac.cn/OpenI/aiforge.git,后续说明已此地址为例}

4. 设置配置文件:
- 在/data/aiforge/custom/conf目录下创建app.ini
- 文件内容如下:
注意:需要将文件中的两个Local_IP替换为本机IP地址
> APP_NAME = aiforge
> RUN_MODE = prod
>
> [repository]
> ROOT = /data/git/repositories
>
> [repository.local]
> LOCAL_COPY_PATH = /data/gitea/tmp/local-repo
>
> [repository.upload]
> TEMP_PATH = /data/gitea/uploads
>
> [server]
> SSH_DOMAIN = 0.0.0.0
> DOMAIN = 0.0.0.0
> HTTP_PORT = 3000
> ROOT_URL = http://0.0.0.0:3000
> DISABLE_SSH = false
> SSH_PORT = 22
> LFS_START_SERVER = true
> LFS_CONTENT_PATH = /data/git/lfs
> LFS_JWT_SECRET = tqVLRkZYpP4UlAoZtZcdX2paFZ6G7FN_Y47It6PfJAE
> OFFLINE_MODE = false
>
> [database]
> DB_TYPE = postgres
> HOST = Local_IP:5432
> NAME = gitea
> USER = gitea
> PASSWD = gitea
> SCHEMA =
> SSL_MODE = disable
> CHARSET = utf8
> PATH = /data/gitea/gitea.db
>
> [database_statistic]
> DB_TYPE = postgres
> HOST = Local_IP:5432
> NAME = statistic
> USER = gitea
> PASSWD = gitea
> SCHEMA =
> SSL_MODE = disable
> CHARSET = utf8
> PATH = /data/gitea/statistic.db
>
> [indexer]
> ISSUE_INDEXER_PATH = /data/gitea/indexers/issues.bleve
>
> [session]
> PROVIDER_CONFIG = /data/gitea/sessions
>
> [picture]
> AVATAR_UPLOAD_PATH = /data/gitea/avatars
> REPOSITORY_AVATAR_UPLOAD_PATH = /data/gitea/repo-avatars
>
> [attachment]
> PATH = /data/gitea/attachments
>
> [log]
> MODE = file
> LEVEL = info
> ROOT_PATH = /data/gitea/log
>
> [security]
> INSTALL_LOCK = true
> SECRET_KEY = sdfsagg453535
>
> [service]
> DISABLE_REGISTRATION = false
> REQUIRE_SIGNIN_VIEW = false
>
> [obs]
>
> ENDPOINT =
>
> ACCESS_KEY_ID =
> SECRET_ACCESS_KEY =
> BUCKET =
> LOCATION =
> BASE_PATH =
> CODE_PATH_PREFIX =
> Output_Path =
> TrainJobModel_Path =
>
> [picture]
> DISABLE_GRAVATAR = true
> ENABLE_FEDERATED_AVATAR = false

5. 编译:
```
cd /data/aiforge
make build
```

6. 运行:
```
./opendata web
```

7. 访问:http://本机ip:8787
注意:代码提交到aiforge请参考[代码提交](https://openi.pcl.ac.cn/docs/index.html#/repo/code.md),[合并请求](https://openi.pcl.ac.cn/docs/index.html#/repo/pr?id=%e5%90%88%e5%b9%b6%e8%af%b7%e6%b1%82)
**特别说明:** 目前无法给开发者提供云脑和智算网络的开发环境,开发者暂时只能参与代码管理相关的任务开发。

## 授权许可

本项目采用 MIT 开源授权许可证,完整的授权说明已放置在 [LICENSE](https://openi.pcl.ac.cn/OpenI/aiforge/src/branch/develop/LICENSE) 文件中。

## 需要帮助?

## 需要帮助?
如果您在使用或者开发过程中遇到问题,可以在以下渠道咨询:
- 点击[这里](https://openi.pcl.ac.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**)
- 加入微信群实时交流,获得进一步的支持
<img src="https://openi.pcl.ac.cn/OpenI/aiforge/wiki/raw/img/wechatgroup.jpg" width=200px />

- 点击[这里](https://openi.pcl.ac.cn/OpenI/aiforge/issues)在线提交问题(点击页面右上角绿色按钮**创建任务**)

- 加入微信群实时交流,获得进一步的支持
<img src="https://openi.pcl.ac.cn/OpenI/aiforge/wiki/raw/img/wechatgroup.jpg" width=200px />

## 小白训练营:

- 结合案例给大家详细讲解如何使用社区平台,帮助无技术背景的小白成长为 达人 (https://openi.pcl.ac.cn/zeizei/OpenI_Learning)

## 平台引用

如果本平台对您的科研工作提供了帮助,可在论文致谢中加入:
英文版:```Thanks for the support provided by OpenI Community (https://openi.pcl.ac.cn).```
中文版:```感谢 提供的技术支持(https://openi.pcl.ac.cn)。```


+ 13
- 0
assets/abandon.svg View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="14px" viewBox="0 0 14 14" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>放弃更改</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-提交" transform="translate(-414.000000, -114.000000)" fill="#9096A3" fill-rule="nonzero">
<g id="编组-8" transform="translate(90.000000, 114.000000)">
<g id="放弃更改" transform="translate(324.000000, 0.000000)">
<path d="M5.64465565,9.44839769 C3.70098527,7.81473925 1.87574642,6.2803543 0.00696656051,4.7093949 C1.86355494,3.14888535 3.69053543,1.61624204 5.60633957,0.00696656051 L5.60633957,2.18575836 C6.64958201,2.31638137 7.63535032,2.37385549 8.58976911,2.57240247 C10.5734972,2.98342954 12.1549064,3.94655653 12.8445959,5.99472532 C13.8408141,8.95028861 12.6599821,12.2263137 10.0057225,13.8564889 C9.96914809,13.8791302 9.92386545,13.8913217 9.82981688,13.9296377 C10.1851115,13.4959693 10.5282146,13.1267416 10.8173268,12.7174562 C11.3885848,11.9128185 11.7212381,11.0176154 11.7595541,10.0213973 C11.7943869,9.12271099 11.3955514,8.46959594 10.6431628,8.01328623 C9.76363455,7.47860271 8.77786624,7.28876393 7.77816481,7.20516521 C7.08499204,7.14769108 6.38485271,7.19471537 5.64465565,7.19471537 L5.64465565,9.44839769 Z" id="路径"></path>
</g>
</g>
</g>
</g>
</svg>

+ 11
- 0
assets/code1.svg View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="24px" viewBox="0 0 22 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>代码1</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-代码" transform="translate(-24.000000, -54.000000)" fill="#FFFFFF" fill-rule="nonzero">
<g id="编组-2" transform="translate(23.000000, 54.000000)">
<path d="M18.691358,20.6530612 C19.3209877,20.6530612 19.8024691,21.4013605 19.8148148,22.3265306 C19.8148148,23.2380952 19.308642,24 18.7037037,24 L5.2962963,24 C4.67901235,24 4.18518519,23.2517007 4.18518519,22.3265306 C4.18518519,21.414966 4.69135802,20.6530612 5.2962963,20.6530612 L18.691358,20.6530612 Z M21.4320988,1.24344979e-14 C22.2962963,1.24344979e-14 23,0.74829932 23,1.67346939 L23,16.707483 L22.9876543,16.707483 C22.9876543,17.6190476 22.2839506,18.3809524 21.4197531,18.3809524 L2.56790123,18.3809524 C1.7037037,18.3809524 1,17.6326531 1,16.707483 L1,1.67346939 C1,0.761904762 1.7037037,1.24344979e-14 2.56790123,1.24344979e-14 L21.4320988,1.24344979e-14 Z M7.40275426,5.59798965 L4.42406571,7.86899844 C4.2208615,8.02209757 4.09361684,8.24213052 4.07053819,8.48032233 C4.04570362,8.87774887 4.05154704,9.27649576 4.08952935,9.67260195 C4.11436392,9.92346921 4.25168453,10.1518904 4.4693523,10.3024108 L7.45096256,12.4215789 C7.80850744,12.6781677 8.30844535,12.6529526 8.6334608,12.3784779 L8.71752605,12.2974656 L8.71752605,12.2974656 C9.05638834,11.8920818 8.97886013,11.3169104 8.54222314,10.996917 L5.87323641,9.10088868 L8.58750971,7.02925332 C8.99780991,6.70122471 9.06310176,6.14433333 8.73797805,5.74586928 C8.58953291,5.5575319 8.36035163,5.43424637 8.10640394,5.40612098 C7.85245625,5.37799559 7.59712068,5.44761958 7.40275426,5.59798965 Z M13.2750251,5.43601868 C13.041601,5.50337484 12.8462407,5.65606881 12.7322875,5.86022349 L9.67682551,11.2791811 C9.51225291,11.5570107 9.51537327,11.896483 9.68502809,12.1715632 C9.85162755,12.4442956 10.1628838,12.6086547 10.4957167,12.5996479 C10.8286146,12.587652 11.1280084,12.4046164 11.2763291,12.1224175 L14.3331583,6.70475316 C14.4492093,6.49817249 14.4756869,6.25696469 14.4069815,6.03223337 C14.340046,5.80948374 14.182814,5.62076308 13.9695104,5.50715059 L13.9681433,5.50715059 C13.7568457,5.39554401 13.5067057,5.36987315 13.2750251,5.43601868 Z M15.8922987,5.40611327 C15.6385591,5.43425376 15.4096876,5.55776951 15.2618761,5.74633526 C14.9356259,6.14558659 15.0029615,6.70437583 15.4166517,7.0307509 L18.129604,9.10060055 L15.4619162,10.9975227 C15.0590628,11.2928349 14.9620467,11.8055279 15.2158996,12.20143 L15.2866986,12.297779 L15.2866986,12.297779 C15.6035504,12.6462741 16.1627866,12.7017165 16.5526457,12.4205444 L19.5328049,10.3044927 C19.750759,10.1515096 19.8883325,9.92333042 19.912443,9.67482542 C19.9489467,9.27880827 19.9547872,8.87883095 19.9270444,8.48149375 L19.9270444,8.48017369 C19.903977,8.24203541 19.7767943,8.02205192 19.573689,7.86898721 L16.5949899,5.59848887 C16.4011465,5.4478137 16.1460382,5.37797278 15.8922987,5.40611327 Z" id="代码1"></path>
</g>
</g>
</g>
</svg>

+ 11
- 0
assets/code2.svg View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="24px" viewBox="0 0 22 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>代码</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-提交" transform="translate(-24.000000, -54.000000)" fill="#000000" fill-rule="nonzero">
<g id="编组-2" transform="translate(23.000000, 54.000000)">
<path d="M18.691358,20.6530612 C19.3209877,20.6530612 19.8024691,21.4013605 19.8148148,22.3265306 C19.8148148,23.2380952 19.308642,24 18.7037037,24 L5.2962963,24 C4.67901235,24 4.18518519,23.2517007 4.18518519,22.3265306 C4.18518519,21.414966 4.69135802,20.6530612 5.2962963,20.6530612 L18.691358,20.6530612 Z M21.4320988,1.24344979e-14 C22.2962963,1.24344979e-14 23,0.74829932 23,1.67346939 L23,16.707483 L22.9876543,16.707483 C22.9876543,17.6190476 22.2839506,18.3809524 21.4197531,18.3809524 L2.56790123,18.3809524 C1.7037037,18.3809524 1,17.6326531 1,16.707483 L1,1.67346939 C1,0.761904762 1.7037037,1.24344979e-14 2.56790123,1.24344979e-14 L21.4320988,1.24344979e-14 Z M7.40275426,5.59798965 L4.42406571,7.86899844 C4.2208615,8.02209757 4.09361684,8.24213052 4.07053819,8.48032233 C4.04570362,8.87774887 4.05154704,9.27649576 4.08952935,9.67260195 C4.11436392,9.92346921 4.25168453,10.1518904 4.4693523,10.3024108 L7.45096256,12.4215789 C7.80850744,12.6781677 8.30844535,12.6529526 8.6334608,12.3784779 L8.71752605,12.2974656 L8.71752605,12.2974656 C9.05638834,11.8920818 8.97886013,11.3169104 8.54222314,10.996917 L5.87323641,9.10088868 L8.58750971,7.02925332 C8.99780991,6.70122471 9.06310176,6.14433333 8.73797805,5.74586928 C8.58953291,5.5575319 8.36035163,5.43424637 8.10640394,5.40612098 C7.85245625,5.37799559 7.59712068,5.44761958 7.40275426,5.59798965 Z M13.2750251,5.43601868 C13.041601,5.50337484 12.8462407,5.65606881 12.7322875,5.86022349 L9.67682551,11.2791811 C9.51225291,11.5570107 9.51537327,11.896483 9.68502809,12.1715632 C9.85162755,12.4442956 10.1628838,12.6086547 10.4957167,12.5996479 C10.8286146,12.587652 11.1280084,12.4046164 11.2763291,12.1224175 L14.3331583,6.70475316 C14.4492093,6.49817249 14.4756869,6.25696469 14.4069815,6.03223337 C14.340046,5.80948374 14.182814,5.62076308 13.9695104,5.50715059 L13.9681433,5.50715059 C13.7568457,5.39554401 13.5067057,5.36987315 13.2750251,5.43601868 Z M15.8922987,5.40611327 C15.6385591,5.43425376 15.4096876,5.55776951 15.2618761,5.74633526 C14.9356259,6.14558659 15.0029615,6.70437583 15.4166517,7.0307509 L18.129604,9.10060055 L15.4619162,10.9975227 C15.0590628,11.2928349 14.9620467,11.8055279 15.2158996,12.20143 L15.2866986,12.297779 L15.2866986,12.297779 C15.6035504,12.6462741 16.1627866,12.7017165 16.5526457,12.4205444 L19.5328049,10.3044927 C19.750759,10.1515096 19.8883325,9.92333042 19.912443,9.67482542 C19.9489467,9.27880827 19.9547872,8.87883095 19.9270444,8.48149375 L19.9270444,8.48017369 C19.903977,8.24203541 19.7767943,8.02205192 19.573689,7.86898721 L16.5949899,5.59848887 C16.4011465,5.4478137 16.1460382,5.37797278 15.8922987,5.40611327 Z" id="代码"></path>
</g>
</g>
</g>
</svg>

+ 13
- 0
assets/codeLog.svg View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="16px" viewBox="0 0 14 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>代码文件</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-提交" transform="translate(-90.000000, -169.000000)" fill="#6F6E6E" fill-rule="nonzero">
<g id="编组-8" transform="translate(90.000000, 114.000000)">
<g id="编组-5" transform="translate(0.000000, 55.000000)">
<path d="M9.72883333,0 C10.0462727,0 10.3500145,0.136417787 10.57,0.377846154 L13.6733333,3.78092308 C13.882631,4.01000077 13.9997061,4.31568263 14,4.63384615 L14,14.7692308 C14,15.4489658 13.4776655,16 12.8333333,16 L1.16666667,16 C0.522334459,16 0,15.4489658 0,14.7692308 L0,1.23076923 C0,0.551034154 0.522334459,0 1.16666667,0 L9.72883333,0 Z M6.36548862,5.17542359 C6.11720692,4.93565488 5.72153765,4.94252988 5.48173828,5.19078174 L5.48173828,5.19078174 L3.18299167,7.48923751 C2.93900277,7.73326904 2.93900277,8.1288445 3.18299173,8.37287604 L3.18299173,8.37287604 L5.48173833,10.6750818 C5.72394113,10.908979 6.1079261,10.908979 6.3501289,10.6750818 C6.59841088,10.4353128 6.60528832,10.0396952 6.36548895,9.79144331 L6.36548895,9.79144331 L4.50923605,7.93043799 L6.3808487,6.05906212 C6.62064776,5.81081183 6.61377188,5.41519262 6.36548862,5.17542359 Z M11.009075,5.01869617 C10.6741417,4.93523201 10.3349555,5.13905256 10.2514799,5.47394202 L10.2514799,5.47394202 L9.02147908,10.0608692 C8.9320786,10.3942696 9.12991167,10.7370085 9.46335425,10.8263983 C9.79679682,10.9157874 10.139579,10.7179794 10.2289801,10.384579 L10.2289801,10.384579 L11.4577308,5.79640184 L11.4589816,5.79640005 L11.4643785,5.77619549 C11.5478532,5.44130448 11.3440069,5.10216127 11.009075,5.01869617 Z" id="代码文件"></path>
</g>
</g>
</g>
</g>
</svg>

+ 11
- 0
assets/drag.svg View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="22px" height="10px" viewBox="0 0 22 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>左右拖动</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-代码" transform="translate(-440.000000, -546.000000)" fill="#6F6E6E" fill-rule="nonzero">
<g id="左右拖动" transform="translate(440.000000, 546.000000)">
<path d="M5.89500984,9.90606823 L0.154266811,5.3158823 C0.0566144941,5.23813069 0,5.12195442 0,4.99931775 C0,4.87668107 0.0566144941,4.76050481 0.154266811,4.6827532 L5.89500984,0.0925672631 C6.02101948,-0.00758660268 6.19515807,-0.0282927778 6.34232468,0.0393787107 C6.48949128,0.107050199 6.58336056,0.250994188 6.58344941,0.409131811 L6.58344941,2.76972089 C6.58344941,2.99579905 6.77215853,3.1790716 7.00494302,3.1790716 L14.996462,3.1790716 C15.2292464,3.1790716 15.4179556,2.99579905 15.4179556,2.76972089 L15.4179556,0.410496313 C15.4180444,0.252358691 15.5119137,0.108414701 15.6590803,0.040743213 C15.8062469,-0.0269282754 15.9803855,-0.00622210032 16.1063951,0.0939317654 L21.8457332,4.6841177 C21.9433855,4.76186931 22,4.87804558 22,5.00068225 C22,5.12331893 21.9433855,5.23949519 21.8457332,5.3172468 L16.1063951,9.90743274 C15.9803855,10.0075866 15.8062469,10.0282928 15.6590803,9.96062129 C15.5119137,9.8929498 15.4180444,9.74900581 15.4179556,9.59086819 L15.4179556,7.23027911 C15.4179556,7.00420095 15.2292464,6.8209284 14.996462,6.8209284 L7.00494302,6.8209284 C6.77215853,6.8209284 6.58344941,7.00420095 6.58344941,7.23027911 L6.58344941,9.59086819 C6.58336056,9.74900581 6.48949128,9.8929498 6.34232468,9.96062129 C6.19515807,10.0282928 6.02101948,10.0075866 5.89500984,9.90743274 L5.89500984,9.90606823 Z" id="路径"></path>
</g>
</g>
</g>
</svg>

BIN
assets/drag2.png View File

Before After
Width: 28  |  Height: 28  |  Size: 801 B

+ 9
- 0
assets/more.svg View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>更多</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-代码" transform="translate(-412.000000, -59.000000)" fill="#9FA5B0">
<path d="M426,59 C427.104569,59 428,59.8954305 428,61 L428,73 C428,74.1045695 427.104569,75 426,75 L414,75 C412.895431,75 412,74.1045695 412,73 L412,61 C412,59.8954305 412.895431,59 414,59 L426,59 Z M416,66 C415.447715,66 415,66.4477153 415,67 C415,67.5522847 415.447715,68 416,68 C416.552285,68 417,67.5522847 417,67 C417,66.4477153 416.552285,66 416,66 Z M420,66 C419.447715,66 419,66.4477153 419,67 C419,67.5522847 419.447715,68 420,68 C420.552285,68 421,67.5522847 421,67 C421,66.4477153 420.552285,66 420,66 Z M424,66 C423.447715,66 423,66.4477153 423,67 C423,67.5522847 423.447715,68 424,68 C424.552285,68 425,67.5522847 425,67 C425,66.4477153 424.552285,66 424,66 Z" id="更多"></path>
</g>
</g>
</svg>

+ 11
- 0
assets/submit.svg View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>提交</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-代码" transform="translate(-23.000000, -124.000000)" fill="#000000" fill-rule="nonzero">
<g id="编组-3" transform="translate(23.000000, 124.000000)">
<path d="M20.1289472,24 L7.67629341,24 C5.45869754,24 3.92343885,22.0588235 3.92343885,19.7647059 C3.92343885,17.4705882 5.79986613,15.8823529 8.01746202,15.8823529 L8.1880463,15.8823529 C8.35863061,14.2941177 9.5527207,12.882353 11.2585637,13.0588235 C11.7703166,13.0588235 12.1114852,13.2352941 12.6232381,13.4117647 C13.3055753,12 14.6702497,11.117647 16.3760926,11.117647 C18.9348571,11.117647 21.152453,13.2352941 21.152453,15.8823529 L21.152453,16.0588235 C23.1994646,16.5882353 24.3935547,18.8823529 23.8818017,21 C23.3700488,22.7647059 21.8347902,23.8235294 20.1289472,24 Z M16.3760926,9.35294117 C14.4996653,9.35294117 12.7938224,10.2352941 11.5997323,11.6470588 L10.7468108,11.6470588 C9.38213639,11.6470588 8.1880463,12.5294118 7.50570911,13.7647059 L0,13.7647059 L0,7.76470589 L22.5171273,7.76470589 L22.5171273,14.2941176 C21.6642058,12 20.1289472,9.17647058 16.3760926,9.35294117 Z M4.09402315,9.1764706 C3.24110165,9.1764706 2.55876448,9.88235296 2.55876448,10.7647059 C2.55876448,11.6470588 3.24110167,12.3529412 4.09402315,12.3529412 C4.94694463,12.3529412 5.62928185,11.6470588 5.62928185,10.7647059 C5.62928185,9.88235296 4.94694465,9.1764706 4.09402315,9.1764706 Z M1.70584298,-5.32907052e-15 L20.8112844,-5.32907052e-15 C21.8347902,-5.32907052e-15 22.5171273,0.705882356 22.5171273,1.7647059 L22.5171273,6 L0,6 L0,1.7647059 C0,0.882352951 0.682337196,-5.32907052e-15 1.70584298,-5.32907052e-15 Z M4.09402315,4.5882353 C4.94694465,4.5882353 5.62928185,3.88235294 5.62928185,3.00000002 C5.62928185,2.11764709 4.94694465,1.41176471 4.09402315,1.41176471 C3.24110165,1.41176471 2.55876448,2.11764707 2.55876448,3.00000002 C2.55876448,3.88235297 3.24110167,4.5882353 4.09402315,4.5882353 L4.09402315,4.5882353 Z M2.55876448,19.9411765 C2.55876448,21.5294117 3.24110167,23.117647 4.43519176,24 L1.70584298,24 C0.682337196,24 0,23.2941176 0,22.2352941 L0,15.3529412 L5.11752893,15.3529412 C3.58227026,16.2352941 2.55876446,18 2.55876448,19.9411765 Z" id="提交"></path>
</g>
</g>
</g>
</svg>

+ 13
- 0
assets/submit2.svg View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="16px" viewBox="0 0 14 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>提交</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-提交" transform="translate(-91.000000, -59.000000)" fill="#000000" fill-rule="nonzero">
<g id="编组-17" transform="translate(91.000000, 59.000000)">
<g id="提交" transform="translate(-0.000000, 0.000000)">
<path d="M13.4778367,15.988073 L9.55310265,15.988073 L9.55310265,15.43347 L9.55310265,15.0458442 L12.972039,15.0458442 L12.972039,0.954155797 L6.14056884,0.954155797 L6.14056884,4.72903466 C6.14056884,4.98922102 5.91411232,5.20014909 5.63477113,5.20014909 C5.62509697,5.20014909 5.61549961,5.19983898 5.60595988,5.19933805 C5.59642015,5.19983898 5.5868228,5.20014909 5.57714861,5.20014909 L1.01856687,5.20014909 L1.01856687,15.0458442 L4.43110069,15.0458442 L4.43110069,15.43347 L4.43110069,15.988073 L0.512769174,15.988073 C0.233427991,15.988073 0.00697148198,15.777145 0.00697148198,15.5169586 L0.00697148198,4.52031308 C0.00697148198,4.40469325 0.0517633795,4.29885948 0.125968379,4.21687961 C0.160010492,4.16720388 0.201492303,4.11953783 0.250183335,4.07557511 L4.51104873,0.228985469 C4.60098467,0.0984748438 4.75803806,0.0119269531 4.93689838,0.0119269531 L13.4778367,0.0119269531 C13.7571778,0.0119269531 13.9836343,0.222855016 13.9836343,0.483041375 L13.9836343,15.5169586 C13.9836343,15.777145 13.7571778,15.988073 13.4778367,15.988073 Z M5.12897344,0.983311219 L1.50169969,4.25792023 L5.12897344,4.25792023 L5.12897344,0.983311219 Z M2.5954584,10.7580947 L2.59340321,9.61971525 L11.8174309,9.61904138 L11.8194925,10.7574268 L2.5954584,10.7580947 Z M2.59340321,6.38751248 L11.8174309,6.38683861 L11.8194925,7.525224 L2.5954584,7.52589191 L2.59340321,6.38751248 Z M2.5954584,9.1419933 L2.59340321,8.00361386 L11.8174309,8.00294 L11.8194925,9.14132537 L2.5954584,9.1419933 Z M7.04972419,11.4171182 L8.63383774,12.8930302 L7.63185892,12.8930302 L7.63239672,14.8444696 L6.41020382,14.845054 L6.40966602,12.8930302 L5.46561062,12.8930302 L7.04972419,11.4171182 Z" id="形状"></path>
</g>
</g>
</g>
</g>
</svg>

+ 11
- 0
assets/warehouse.svg View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="14px" height="16px" viewBox="0 0 14 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>代码仓库</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Manaco-代码" transform="translate(-90.000000, -59.000000)" fill="#000000" fill-rule="nonzero">
<g id="代码仓库" transform="translate(90.000000, 59.000000)">
<path d="M13.5574941,6.11252215 L7.7074972,0.29324975 L7.70749726,0.293249807 C7.31718961,-0.0974428356 6.68402439,-0.0977943985 6.29328388,0.29246314 C6.29302151,0.292725179 6.2927593,0.292987362 6.29249722,0.293249694 L0.442500285,6.11252209 L0.442500249,6.11252213 C0.159278149,6.3940287 0,6.77683852 0,7.17613743 L0,14.5002084 L0,14.5002082 C0,15.3285311 0.671573248,16.0000193 1.5,16.0000193 L12.5,16.0000193 L12.5,16.0000193 C13.3284268,16.0000193 14,15.3285311 14,14.5002082 C14,14.5002082 14,14.5002082 14,14.5002082 L14,7.17613718 L14,7.17619816 C14,6.77689769 13.8407531,6.39408162 13.5575435,6.11256411 L13.5574941,6.11252215 Z M6.36499767,11.8617945 L6.36499768,11.8617945 C6.60479705,12.1100463 6.5979196,12.505664 6.34963762,12.745433 C6.10743482,12.9793301 5.72344986,12.9793301 5.48124706,12.745433 L3.18250042,10.4432272 L3.18250045,10.4432272 C2.93851149,10.1991957 2.93851149,9.80362021 3.18250039,9.55958868 L5.48124703,7.26113288 L5.481247,7.2611329 C5.72104637,7.01288105 6.11671564,7.00600604 6.36499734,7.24577476 C6.6132806,7.48554379 6.62015648,7.881163 6.38035743,8.12941329 C6.37532678,8.13462123 6.37020601,8.13974136 6.3649974,8.14477137 L4.50874477,10.0007892 L6.36499767,11.8617945 Z M10.978743,7.86855544 L9.74999237,12.4567327 L9.74999239,12.4567326 C9.66059128,12.790133 9.31780908,12.987941 8.98436651,12.8985518 C8.65092393,12.8091621 8.45309086,12.4664232 8.54249134,12.1330228 L9.77249213,7.54609562 L9.77249214,7.54609561 C9.8559678,7.21120616 10.1951539,7.00738561 10.5300873,7.09084977 C10.8650191,7.17431487 11.0688655,7.51345807 10.9853908,7.84834909 C10.9837046,7.85511356 10.9819054,7.86184935 10.9799938,7.86855364 L10.978743,7.86855544 Z" id="形状"></path>
</g>
</g>
</g>
</svg>

+ 0
- 45
custom/public/img/logo-w-origin.svg View File

@@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 160 64" style="enable-background:new 0 0 160 64;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{display:none;fill:#FFFFFF;}
</style>
<g>
<path class="st0" d="M105.3,33.3H87.1c-2.6,0.1-4,1.3-4,3.8v8.3c0.1,2.2,1.5,3.3,4,3.5h18c2.5-0.1,3.8-1.3,3.9-3.6v-8.2
c0.1-2-1.4-3.6-3.4-3.8C105.6,33.3,105.4,33.3,105.3,33.3z M104.6,43.9c-0.1,1-0.7,1.5-1.9,1.7H89.3c-1.3-0.3-1.8-0.7-1.9-1.7v-5.4
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0h13.1c1.1,0,2,0.8,2.1,2L104.6,43.9z"/>
<path class="st0" d="M81,25.3v-4.7c0-1.1,0.9-2.1,2.1-2.1h19c1.4-0.1,2.1,0.5,2.1,1.8v3.3c0,1.1-0.7,1.7-1.9,1.7H82.8v3.2H105
c2.3,0,3.6-1.1,3.6-3.2v-6.4c0.2-1.8-1.1-3.4-2.8-3.6c-0.3,0-0.5,0-0.8,0h-9.7v-2.6h-4.6v2.6H80.3c-2.6,0-3.9,1.2-3.9,3.9v12.3
c0,5.8-0.9,11.6-2.6,17.1l4.3,0.8c1.8-5.5,2.7-11.3,2.8-17.1v-7.2H81z"/>
<path class="st0" d="M116.2,30.4l4.4,2.4c2.6-1.9,4.4-4.6,5.1-7.6h7.8v-3.2h-7.1c0.2-1.3,0.3-2.6,0.3-3.9h6.6v-3.2h-12.3v-2h-4.6
V18h5.8c0,1.3-0.1,2.6-0.3,3.9h-6.7v3.3h5.8C120.4,27.5,118.6,29.4,116.2,30.4z"/>
<path class="st0" d="M126.5,26.7c1.2,1.8,2.1,3.8,2.9,5.8h4.9c-0.8-2-1.8-4-2.9-5.8H126.5z"/>
<path class="st0" d="M145.4,33.5h-24.7c-2.4,0.3-3.8,1.4-3.9,3.5v6.2h28.4v1.3c0,1.1-0.7,1.7-2.1,1.7h-19.7c-1.3,0-1.9-0.5-1.9-1.5
h-4.5V46c0,1.9,1.6,3.5,3.5,3.6h25.1c2.6-0.1,4-1.3,4-3.5v-9C149.2,35,147.5,33.5,145.4,33.5z M145,39.9h-23.7v-1.1
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0H143c1.3,0,2.1,0.7,2.1,1.9L145,39.9z"/>
<path class="st0" d="M147.3,14h-8.2c-2.2,0.1-3.5,1.1-3.8,2.9v11.7c0.1,1.6,1.4,2.9,3.1,2.9h8.7c1.9-0.1,3.1-1.1,3.1-2.9V17
C150.4,15.4,149.4,14.3,147.3,14z M146,26.2c0,1.4-0.7,2.1-1.9,2.1h-2.4c-1,0-1.8-0.8-1.8-1.8c0-0.1,0-0.1,0-0.2v-7
c0-1,0.8-1.9,1.8-1.9c0,0,0.1,0,0.1,0h2c1.1,0,2.1,0.8,2.1,1.9l0,0L146,26.2z"/>
</g>
<path class="st1" d="M67.2,44.1V20c0-2.6-1.4-5.1-3.7-6.4l-20.9-12c-2.3-1.3-5.1-1.3-7.4,0l-20.9,12c-2.3,1.3-3.7,3.8-3.7,6.4v24.1
c0,2.6,1.4,5.1,3.7,6.4l20.9,12c2.3,1.3,5.1,1.3,7.4,0l20.9-12C65.8,49.2,67.2,46.7,67.2,44.1z"/>
<path class="st0" d="M61.9,15.4L42,3.9c-1.9-1.1-4.3-1.1-6.2,0L15.9,15.4c-1.9,1.1-3.1,3.2-3.1,5.4v22.9c0,2.2,1.2,4.3,3.1,5.4
l3.8,2c0.8,0.4,0.8,1,0.8,1.9c0,0,0,0.1,0,0.1c0.1,1.6,1.8,3.5,4.2,3.5c2.3,0,4.3-1.9,4.4-4.2c0-1.6-0.8-3.1-2.3-3.9
c-0.6-0.3-1.7-0.5-2.9-0.4c-0.9,0.1-1,0.6-2.8-0.5l-2.8-1.6c-0.8-0.5-1.7-1.3-1.6-2.3V22c0-1.8,0.8-2.8,2.1-3.5L37,7.8
C38.1,7,40.2,7.2,41.5,8l16.4,9.5c2.9,1.6,3,3,3,4v19.7c0,2.3-1.5,4-2.3,4.5l-15.1,8.5C42.8,54.5,42,54,42,53.3l0-2.5
c0-0.1,0-0.3,0-0.4v-2.5c0-0.8,0.4-1.6,1.1-2l8.8-5.7c1.4-0.9,2-1.7,2-3.8L53.7,28c0-1,0.4-1.9,1.2-2.5c1.5-1.3,2-3.7,0.8-5.6
c-0.8-1.4-2.4-2.2-4-2c-1.6,0.1-2.8,1-3.5,2.4c-0.5,1-0.6,2.2-0.3,3.3c0.2,0.8,0.7,1.4,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5v7.2
c0,1.1-0.5,2.1-1.5,2.7l-5.5,2.8c-0.7,0.5-1.6,0-1.6-0.8l-0.2-17.1c0-1,0.5-1.9,1.2-2.5c0.4-0.3,0.7-0.8,1-1.3
c0.7-1.3,0.7-2.9-0.1-4.3c-0.8-1.4-2.5-2.2-4.1-2.1c-2.9,0.3-4.6,3.1-3.8,5.7c0.2,0.8,0.7,1.4,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5v9.9
c0,0.8-0.8,1.3-1.5,0.9L34,32.5c-0.7-0.4-1.2-1.2-1.2-2.1v-2.2c0-1,0.4-1.9,1.2-2.5c1.5-1.3,2-3.7,0.8-5.6c-0.8-1.3-2.4-2.1-4-2
c-2.9,0.2-4.7,3.1-3.8,5.7c0.2,0.8,0.7,1.5,1.3,2c0.7,0.6,1.2,1.5,1.2,2.5l0,3.5c0,1,0,2,1.6,3.1l5.5,3c0.7,0.4,1.2,1.2,1.2,2.1v4.5
c0,0.8-0.8,1.3-1.5,0.9L26.6,41c-0.7-0.4-1.2-1.2-1.2-2.1l-0.2-6.1c0-1,0.4-1.8,1.1-2.5c1.4-1.3,1.9-3.4,0.9-5.3
c-0.8-1.4-2.4-2.3-4-2.2c-2.9,0.2-4.6,3-3.8,5.6c0.2,0.7,0.7,1.4,1.2,1.9c0.7,0.6,1.1,1.5,1.1,2.5l-0.5,6.8c0,1.9,0.3,2.8,1.8,3.5
l11.8,6.3c1,0.6,1.6,1.7,1.6,2.8l0,3.1c0,3.1,4.3,5.7,8.7,3.3l16.4-9.8c1.9-1,3.2-3,3.4-5.2V20.7C65,18.5,63.8,16.5,61.9,15.4z
M24.2,50.7c1.1,0,2,0.9,2,2c0,1.1-0.9,2-2,2c-1.1,0-2-0.9-2-2C22.2,51.7,23.1,50.7,24.2,50.7z M48.7,21.5c0-1.1,0.9-2,2-2
s2,0.9,2,2c0,1.1-0.9,2-2,2S48.7,22.6,48.7,21.5z M30.6,23.8c-1.1,0-2-0.9-2-2s0.9-2,2-2c1.1,0,2,0.9,2,2S31.8,23.8,30.6,23.8z
M22.2,26.4c0-1.1,0.9-2,2-2c1.1,0,2,0.9,2,2s-0.9,2-2,2C23.1,28.4,22.2,27.5,22.2,26.4z M40,17.9c-1.1,0-2-0.9-2-2c0-1.1,0.9-2,2-2
c1.1,0,2,0.9,2,2C42,17,41.1,17.9,40,17.9z"/>
</svg>

+ 45
- 1
custom/public/img/logo-w.svg
File diff suppressed because it is too large
View File


BIN
go_build_code_gitea_io_gitea View File


+ 109
- 47
models/cloudbrain.go View File

@@ -63,6 +63,7 @@ const (
JobTypeSnn4imagenet JobType = "SNN4IMAGENET"
JobTypeBrainScore JobType = "BRAINSCORE"
JobTypeSnn4Ecoset JobType = "SNN4ECOSET"
JobTypeSim2BrainSNN JobType = "SIM2BRAIN_SNN"
JobTypeTrain JobType = "TRAIN"
JobTypeInference JobType = "INFERENCE"

@@ -287,14 +288,54 @@ func (task *Cloudbrain) CorrectCreateUnix() {
}
}

func AllTerminalStatus() []string {
return []string{string(ModelArtsTrainJobCompleted), string(ModelArtsTrainJobFailed),
string(ModelArtsTrainJobKilled), string(ModelArtsStopped),
string(JobStopped), string(JobFailed),
string(JobSucceeded), GrampusStatusFailed,
GrampusStatusSucceeded, GrampusStatusStopped}
}

func AllStoppingStatus() []string {
return []string{string(ModelArtsStopping), string(ModelArtsDeleting),
string(ModelArtsTrainJobKilling), GrampusStatusStopping}
}
func AllRunningOrWaitingStatus() []string {
return []string{string(JobRunning), string(JobWaiting),
string(ModelArtsCreating), string(ModelArtsStartQueuing),
string(ModelArtsReadyToStart), string(ModelArtsCreateQueue),
string(ModelArtsStarting), string(ModelArtsRestarting),
string(ModelArtsRunning), string(ModelArtsTrainJobSubmitTrying),
string(ModelArtsTrainJobWaiting), string(ModelArtsTrainJobRunning),
GrampusStatusPending, GrampusStatusRunning, GrampusStatusWaiting,
}
}

func AllStoppingAndTerminalStatus() []string {
var status = AllTerminalStatus()
return append(status, AllStoppingStatus()...)
}

func (task *Cloudbrain) IsTerminal() bool {
status := task.Status
return status == string(ModelArtsTrainJobCompleted) || status == string(ModelArtsTrainJobFailed) ||
status == string(ModelArtsTrainJobKilled) || status == string(ModelArtsStopped) ||
status == string(JobStopped) || status == string(JobFailed) ||
status == string(JobSucceeded) || status == GrampusStatusFailed ||
status == GrampusStatusSucceeded || status == GrampusStatusStopped
for _, s := range AllTerminalStatus() {
if status == s {
return true
}
}
return false
}

func (task *Cloudbrain) IsTerminalOrStopping() bool {
status := task.Status
for _, s := range AllStoppingAndTerminalStatus() {
if status == s {
return true
}
}
return false
}

func (task *Cloudbrain) IsRunning() bool {
status := task.Status
return status == string(ModelArtsTrainJobRunning) || status == string(ModelArtsRunning) ||
@@ -346,18 +387,32 @@ func IsModelArtsDebugJobTerminal(status string) bool {
func IsCloudBrainOneDebugJobTerminal(status string) bool {
return status == string(JobStopped) || status == string(JobFailed) || status == string(JobSucceeded)
}
func IsModelBenchMarkJobType(jobType string) bool {
types := AllBenchMarkJobTYpe()
func IsBenchMarkJobType(jobType string) bool {
types := AllBenchMarkJobType()
for _, t := range types {
if jobType == string(t) {
if jobType == t {
return true
}
}
return false
}

func AllBenchMarkJobTYpe() []JobType {
return []JobType{JobTypeBenchmark, JobTypeModelSafety, JobTypeSnn4imagenet, JobTypeBrainScore, JobTypeSnn4Ecoset}
func AllJobType() []string {
jobTypes := make([]string, 0)
jobTypes = append(jobTypes, string(JobTypeDebug), string(JobTypeTrain), string(JobTypeInference))
jobTypes = append(jobTypes, AllBenchMarkJobType()...)
return jobTypes
}

func AllBenchMarkJobType() []string {
jobTypes := make([]string, 0)
jobTypes = append(jobTypes, string(JobTypeBenchmark), string(JobTypeModelSafety))
jobTypes = append(jobTypes, AllModelMarkJobType()...)
return jobTypes
}

func AllModelMarkJobType() []string {
return []string{string(JobTypeSnn4imagenet), string(JobTypeBrainScore), string(JobTypeSnn4Ecoset), string(JobTypeSim2BrainSNN)}
}

func ParseAndSetDurationFromCloudBrainOne(result JobResultPayload, task *Cloudbrain) {
@@ -365,7 +420,7 @@ func ParseAndSetDurationFromCloudBrainOne(result JobResultPayload, task *Cloudbr
if task.StartTime == 0 && isActivated {
task.StartTime = timeutil.TimeStamp(result.JobStatus.CreatedTime / 1000)
}
if task.EndTime == 0 && IsCloudBrainOneDebugJobTerminal(task.Status) && isActivated {
if task.EndTime == 0 && IsCloudBrainOneDebugJobTerminal(result.JobStatus.State) && isActivated {
if result.JobStatus.CompletedTime > 0 {
task.EndTime = timeutil.TimeStamp(result.JobStatus.CompletedTime / 1000)
}
@@ -473,32 +528,33 @@ type GetImagesPayload struct {

type CloudbrainsOptions struct {
ListOptions
RepoID int64 // include all repos if empty
UserID int64
JobID string
SortType string
CloudbrainIDs []int64
JobStatus []string
JobStatusNot bool
Keyword string
Type int
JobTypes []string
VersionName string
IsLatestVersion string
JobTypeNot bool
NeedRepoInfo bool
RepoIDList []int64
BeginTime time.Time
EndTime time.Time
ComputeResource string
BeginTimeUnix int64
EndTimeUnix int64
AiCenter string
NeedDeleteInfo string
Cluster string
AccCardType string
AccCardsNum int
WorkServerNumber int
RepoID int64 // include all repos if empty
UserID int64
JobID string
SortType string
CloudbrainIDs []int64
JobStatus []string
JobStatusNot bool
Keyword string
Type int
JobTypes []string
VersionName string
IsLatestVersion string
JobTypeNot bool
NeedRepoInfo bool
RepoIDList []int64
BeginTime time.Time
EndTime time.Time
ComputeResource string
BeginTimeUnix int64
EndTimeUnix int64
DateBeginTimeUnix int64
AiCenter string
NeedDeleteInfo string
Cluster string
AccCardType string
AccCardsNum int
WorkServerNumber int
}

type TaskPod struct {
@@ -1845,10 +1901,10 @@ func QueryModelTrainJobVersionList(jobId string) ([]*Cloudbrain, int, error) {
cond = cond.And(
builder.Eq{"cloudbrain.job_id": jobId},
)
cond = cond.And(
builder.In("cloudbrain.Status", "COMPLETED", "SUCCEEDED"),
//builder.Eq{"cloudbrain.Status": "COMPLETED"},
)
// cond = cond.And(
// builder.In("cloudbrain.Status", "COMPLETED", "SUCCEEDED"),
// //builder.Eq{"cloudbrain.Status": "COMPLETED"},
// )

sess.OrderBy("cloudbrain.created_unix DESC")
cloudbrains := make([]*Cloudbrain, 0)
@@ -1867,9 +1923,9 @@ func QueryModelTrainJobList(repoId int64) ([]*Cloudbrain, int, error) {
cond = cond.And(
builder.Eq{"repo_id": repoId},
)
cond = cond.And(
builder.In("Status", "COMPLETED", "SUCCEEDED"),
)
// cond = cond.And(
// builder.In("Status", "COMPLETED", "SUCCEEDED"),
// )
cond = cond.And(
builder.Eq{"job_type": "TRAIN"},
)
@@ -2201,7 +2257,7 @@ func GetCloudBrainUnStoppedJob() ([]*Cloudbrain, error) {
JobStopped, JobSucceeded, JobFailed, ModelArtsCreateFailed, ModelArtsStartFailed, ModelArtsUnavailable, ModelArtsResizFailed, ModelArtsDeleted,
ModelArtsStopped, ModelArtsTrainJobCanceled, ModelArtsTrainJobCheckFailed, ModelArtsTrainJobCompleted, ModelArtsTrainJobDeleteFailed, ModelArtsTrainJobDeployServiceFailed,
ModelArtsTrainJobFailed, ModelArtsTrainJobImageFailed, ModelArtsTrainJobKilled, ModelArtsTrainJobLost, ModelArtsTrainJobSubmitFailed, ModelArtsTrainJobSubmitModelFailed).
Limit(100).
// Limit(1000).
Find(&cloudbrains)
}

@@ -2334,7 +2390,7 @@ func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTy
}
return sess.Count(new(Cloudbrain))
}
func GetNotFinalStatusTaskCount(userID int64, notFinalStatus []string, jobTypes []JobType) (int, error) {
func GetNotFinalStatusTaskCount(userID int64, notFinalStatus []string, jobTypes []string) (int, error) {
count, err := x.In("status", notFinalStatus).
In("job_type", jobTypes).
And("user_id = ? ", userID).Count(new(Cloudbrain))
@@ -2564,6 +2620,12 @@ func CloudbrainAllStatic(opts *CloudbrainsOptions) ([]*CloudbrainInfo, int64, er
builder.And(builder.Gte{"cloudbrain.created_unix": opts.BeginTimeUnix}, builder.Lte{"cloudbrain.created_unix": opts.EndTimeUnix}),
)
}
if opts.DateBeginTimeUnix > 0 || len(opts.JobStatus) > 0 {
cond = cond.And(builder.Or(
builder.Gte{"cloudbrain.end_time": opts.DateBeginTimeUnix},
builder.In("cloudbrain.status", opts.JobStatus),
))
}
var count int64
var err error
count, err = sess.Unscoped().Where(cond).Count(new(Cloudbrain))
@@ -2824,7 +2886,7 @@ func LoadSpecs(tasks []*Cloudbrain) error {
}
specMap := make(map[int64]*CloudbrainSpec)
for _, v := range specs {
specMap[v.SpecId] = v
specMap[v.CloudbrainID] = v
}
for _, v := range tasks {
if specMap[v.ID] != nil {


+ 31
- 47
models/cloudbrain_static.go View File

@@ -6,7 +6,6 @@ import (

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
)

@@ -234,57 +233,42 @@ func GetRunningTop() ([]*CloudbrainInfo, error) {
return cloudbrains, nil
}

func getCreatePeriodCount(dateBeginTime string, dateEndTime string, hourBeginTime string, hourEndTime string) (int64, error) {
countSql := "SELECT count(*) FROM " +
"public.cloudbrain where to_char(to_timestamp(created_unix), 'YYYY-MM-DD') >= '" + dateBeginTime +
"' and to_char(to_timestamp(created_unix), 'YYYY-MM-DD') < '" + dateEndTime +
"' and to_char(to_timestamp(created_unix), 'HH24:MI:SS') >= '" + hourBeginTime +
"' and to_char(to_timestamp(created_unix), 'HH24:MI:SS') < '" + hourEndTime + "'"
return x.SQL(countSql).Count()
}

//SELECT * FROM xxx WHERE NOT ((endTime < hourBeginTime) OR (startTime > hourEndTime))
func getRunPeriodCount(dateBeginTime string, dateEndTime string, hourBeginTime string, hourEndTime string) (int64, error) {
countSql := "SELECT count(*) FROM " +
"public.cloudbrain where not ((to_char(to_timestamp(start_time), ' HH24:MI:SS') > '" + hourEndTime +
"') or (to_char(to_timestamp(end_time), 'HH24:MI:SS') < '" + hourBeginTime + "'))" +
" and (to_char(to_timestamp(start_time), 'YYYY-MM-DD') >= '" + dateBeginTime +
"' and to_char(to_timestamp(start_time), 'YYYY-MM-DD') < '" + dateEndTime + "')"
return x.SQL(countSql).Count()

func GetCreateHourPeriodCount(cloudbrains []*CloudbrainInfo, dateBeginTime time.Time, dateEndTime time.Time) (map[string]int64, error) {
var createHourPeriodCount = make(map[string]int64)
for _, cloudbrain := range cloudbrains {
if cloudbrain.StartTime != 0 && cloudbrain.EndTime == 0 {
cloudbrain.EndTime = timeutil.TimeStamp(time.Now().Unix())
}
hourBeginTime := dateBeginTime.Unix()
hourEndTime := hourBeginTime + int64(3600)
for hour := 0; hour < 24; hour++ {
if int64(cloudbrain.Cloudbrain.CreatedUnix) >= hourBeginTime && int64(cloudbrain.Cloudbrain.CreatedUnix) < hourEndTime {
createHourPeriodCount[strconv.Itoa(hour)] = createHourPeriodCount[strconv.Itoa(hour)] + 1
}
hourBeginTime = hourEndTime
hourEndTime = hourEndTime + int64(3600)
}
}
return createHourPeriodCount, nil
}

func GetCreateHourPeriodCount(dateBeginTime string, dateEndTime string) (map[string]interface{}, error) {
//0 to 23 for each hour,
dateHourMap := make(map[string]interface{})
var slice = []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
for key, value := range slice {
hourBeginHour := util.AddZero(value) + ":00:00"
hourEndHour := util.AddZero(value+1) + ":00:00"
cout, err := getCreatePeriodCount(dateBeginTime, dateEndTime, hourBeginHour, hourEndHour)
if err != nil {
log.Error("Can not query getCreatePeriodCount.", err)
return nil, nil
func GetRunHourPeriodCount(cloudbrains []*CloudbrainInfo, dateBeginTime time.Time, dateEndTime time.Time) (map[string]int64, error) {
var runHourPeriodCount = make(map[string]int64)
for _, cloudbrain := range cloudbrains {
if cloudbrain.StartTime != 0 && cloudbrain.EndTime == 0 {
cloudbrain.EndTime = timeutil.TimeStamp(time.Now().Unix())
}
dateHourMap[strconv.Itoa(key)] = cout
}
return dateHourMap, nil
}

func GetRunHourPeriodCount(dateBeginTime string, dateEndTime string) (map[string]interface{}, error) {
dateHourMap := make(map[string]interface{})
var slice = []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
for key, value := range slice {
hourBeginHour := util.AddZero(value) + ":00:00"
hourEndHour := util.AddZero(value+1) + ":00:00"
cout, err := getRunPeriodCount(dateBeginTime, dateEndTime, hourBeginHour, hourEndHour)
if err != nil {
log.Error("Can not query getRunPeriodCount.", err)
return nil, nil
hourBeginTime := dateBeginTime.Unix()
hourEndTime := hourBeginTime + int64(3600)
for hour := 0; hour < 24; hour++ {
if cloudbrain.StartTime.AsTime().Unix() < hourEndTime && cloudbrain.EndTime.AsTime().Unix() > hourBeginTime {
runHourPeriodCount[strconv.Itoa(hour)] = runHourPeriodCount[strconv.Itoa(hour)] + 1
}
hourBeginTime = hourEndTime
hourEndTime = hourEndTime + int64(3600)
}
dateHourMap[strconv.Itoa(key)] = cout
}
return dateHourMap, nil
return runHourPeriodCount, nil
}

func GetCloudbrainRunning() ([]*CloudbrainInfo, error) {


+ 14
- 0
models/error.go View File

@@ -7,6 +7,7 @@ package models

import (
"fmt"
pg "github.com/lib/pq"

"code.gitea.io/gitea/modules/git"
)
@@ -2036,3 +2037,16 @@ func IsErrInsufficientPointsBalance(err error) bool {
func (err ErrInsufficientPointsBalance) Error() string {
return fmt.Sprintf("Insufficient points balance")
}

func IsPGErrUniqueViolation(err error) bool {
if err != nil {
e := err.(*pg.Error)
//23505 is postgrey error code for unique_violation
//see https://www.postgresql.org/docs/current/errcodes-appendix.html
//if unique_violation,user role record exists,just return
if e.Code == "23505" {
return true
}
}
return false
}

+ 66
- 0
models/modelapp.go View File

@@ -0,0 +1,66 @@
package models

import (
"fmt"

"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
)

type ModelApp struct {
ID string `xorm:"pk"`
Desc string `xorm:"varchar(1000)"`
Count int
UserId int64 `xorm:"INDEX"`
ExternalID string
Picture string `xorm:"text NULL"` //picture base64
Status int
CreatedUnix timeutil.TimeStamp `xorm:"created"`
UpdatedUnix timeutil.TimeStamp `xorm:"updated"`
}

func SaveModelApp(modelApp *ModelApp) error {
statictisSess := xStatistic.NewSession()
defer statictisSess.Close()
re, err := statictisSess.Insert(modelApp)
if err != nil {
log.Info("insert modelApp error." + err.Error())
return err
}
log.Info("success to save modelApp db.re=" + fmt.Sprint((re)))
return nil
}

func UpdateModelApp(modelApp *ModelApp) error {
statictisSess := xStatistic.ID(modelApp.ID)
defer statictisSess.Close()
re, err := statictisSess.Cols("picture", "status").Update(modelApp)
if err != nil {
return err
}
log.Info("update modelApp db.re=" + fmt.Sprint((re)))
return nil
}

func QueryModelAppById(id string) *ModelApp {
statictisSess := xStatistic.NewSession()
defer statictisSess.Close()
re := new(ModelApp)
isExist, err := statictisSess.Table(new(ModelApp)).ID(id).Get(re)
if err == nil && isExist {
return re
}
return nil
}

func QueryModelAppCount(userId int64) int64 {
statictisSess := xStatistic.NewSession()
defer statictisSess.Close()
sumList, err := statictisSess.QueryInterface("select sum(count) as count from public.model_app where user_id=" + fmt.Sprint(userId))
if err == nil {
if len(sumList) == 1 {
return convertInterfaceToInt64(sumList[0]["count"])
}
}
return 0
}

+ 4
- 0
models/models.go View File

@@ -167,6 +167,9 @@ func init() {
new(Badge),
new(BadgeUser),
new(BadgeUserLog),
new(TechConvergeBaseInfo),
new(RepoConvergeInfo),
new(UserRole),
)

tablesStatistic = append(tablesStatistic,
@@ -187,6 +190,7 @@ func init() {
new(Invitation),
new(CloudbrainDurationStatistic),
new(UserSummaryCurrentYear),
new(ModelApp),
)

gonicNames := []string{"SSL", "UID"}


+ 4
- 4
models/point_account.go View File

@@ -30,8 +30,8 @@ type PointAccount struct {
func (account *PointAccount) Increase(amount int64, sourceId string) error {
sess := x.NewSession()
defer sess.Close()
sql := "update point_account set balance = balance + ?,total_earned = total_earned + ? ,version = version + 1 where account_code = ? "
_, err := sess.Exec(sql, amount, amount, account.AccountCode)
sql := "update point_account set balance = balance + ?,total_earned = total_earned + ? ,version = version + 1,updated_unix = ? where account_code = ? "
_, err := sess.Exec(sql, amount, amount, timeutil.TimeStampNow(), account.AccountCode)
if err != nil {
sess.Rollback()
return err
@@ -58,8 +58,8 @@ func (account *PointAccount) Increase(amount int64, sourceId string) error {
func (account *PointAccount) Decrease(amount int64, sourceId string) error {
sess := x.NewSession()
defer sess.Close()
sql := "update point_account set balance = balance - ?,total_consumed = total_consumed + ? ,version = version + 1 where account_code = ? "
_, err := sess.Exec(sql, amount, amount, account.AccountCode)
sql := "update point_account set balance = balance - ?,total_consumed = total_consumed + ? ,version = version + 1 ,updated_unix = ? where account_code = ? "
_, err := sess.Exec(sql, amount, amount, timeutil.TimeStampNow(), account.AccountCode)
if err != nil {
sess.Rollback()
return err


+ 1
- 0
models/repo.go View File

@@ -231,6 +231,7 @@ type Repository struct {
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`

CurrentBranch string
Hot int64 `xorm:"-"`
Active int64 `xorm:"-"`
Alias string `xorm:"INDEX"`


+ 30
- 0
models/repo_list.go View File

@@ -192,6 +192,8 @@ type SearchRepoOptions struct {
// False -> include just no courses
Course util.OptionalBool
OnlySearchPrivate bool

RepoIds []int64
}

//SearchOrderBy is used to sort the result
@@ -206,6 +208,7 @@ type FindReposResponse struct {
Page int
PageSize int
Total int64
RepoIds []int64
}

// Strings for sorting result
@@ -281,6 +284,33 @@ func SearchRepositoryCondition(opts *SearchRepoOptions) builder.Cond {
if opts.StarredByID > 0 {
cond = cond.And(builder.In("id", builder.Select("repo_id").From("star").Where(builder.Eq{"uid": opts.StarredByID})))
}
if len(opts.RepoIds) > 0 {
const MaxINItems = 1000
if len(opts.RepoIds) <= MaxINItems {
cond = cond.And(builder.In("id", opts.RepoIds))
} else {
repoIdsMap := make(map[int][]int64, 0)
i := 0

for j := 0; j < len(opts.RepoIds); j++ {
if _, ok := repoIdsMap[i]; !ok {
repoIdsMap[i] = make([]int64, 0)
}
repoIdsMap[i] = append(repoIdsMap[i], opts.RepoIds[j])
if (j+1)%MaxINItems == 0 {
i += 1
}

}
subCond := builder.NewCond()
for _, repoSplit := range repoIdsMap {
subCond = subCond.Or(builder.In("id", repoSplit))
}
cond = cond.And(subCond)

}

}

// Restrict repositories to those the OwnerID owns or contributes to as per opts.Collaborate
if opts.OwnerID > 0 {


+ 17
- 0
models/reward_admin_log.go View File

@@ -38,6 +38,23 @@ type AdminLogAndUser struct {
User User `xorm:"extends"`
}

type PointUser struct {
UserId string
UserName string
Amount string
Remark string
}

type CSVFailedData struct {
PointUser PointUser
ErrorMsg string
}
type BatchRewardPointReturnData struct {
SuccessNum int
FailedNum int
CSVFailedDatas []CSVFailedData
}

func getRewardAdminLog(ra *RewardAdminLog) (*RewardAdminLog, error) {
has, err := x.Get(ra)
if err != nil {


+ 73
- 0
models/role.go View File

@@ -0,0 +1,73 @@
package models

import (
"fmt"

"code.gitea.io/gitea/modules/timeutil"
)

type RoleType string

const (
TechProgramAdmin RoleType = "TechProgramAdmin"
RewardPointAdmin RoleType = "RewardPointAdmin"
)

type Role struct {
Type RoleType
Name string
Description string
}

type UserRole struct {
ID int64 `xorm:"pk autoincr"`
UserId int64 `xorm:"INDEX UNIQUE(uq_user_role)"`
RoleType RoleType `xorm:"UNIQUE(uq_user_role)"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
}

func NewUserRole(r UserRole) (int64, error) {
return x.Insert(&r)
}
func DeleteUserRole(roleType RoleType, userId int64) (int64, error) {
return x.Where("role_type = ? and user_id = ?", roleType, userId).Delete(&UserRole{})
}

func GetUserRoleByUserAndRole(userId int64, roleType RoleType) (*UserRole, error) {
r := &UserRole{}
has, err := x.Where("role_type = ? and user_id = ?", roleType, userId).Get(r)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRecordNotExist{}
}
return r, nil
}

func GetRoleByCode(code string) (*Role, error) {
r := &Role{}
has, err := x.Where("code = ?", code).Get(r)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRecordNotExist{}
}
return r, nil
}

type ErrRoleNotExists struct {
}

func IsErrRoleNotExists(err error) bool {
_, ok := err.(ErrRoleNotExists)
return ok
}

func (err ErrRoleNotExists) Error() string {
return fmt.Sprintf("role is not exists")
}

type OperateRoleReq struct {
UserName string `json:"user_name" binding:"Required"`
RoleType RoleType `json:"role_type" binding:"Required"`
}

+ 661
- 0
models/tech_converge_info.go View File

@@ -0,0 +1,661 @@
package models

import (
"strconv"
"strings"
"time"

"code.gitea.io/gitea/modules/timeutil"
"xorm.io/builder"
)

const (
TechShow = 1
TechHide = 2
TechMigrating = 3
TechMigrateFailed = 4
TechNotExist = 5
)

const DefaultTechApprovedStatus = TechShow

type TechConvergeBaseInfo struct {
ID int64 `xorm:"pk autoincr"`
ProjectNumber string `xorm:"UNIQUE NOT NULL"` //项目立项编号
ProjectName string //科技项目名称
Institution string //项目承担单位
ApplyYear int //申报年度
Province string //所属省(省市)
Category string //单位性质
Recommend string //推荐单位
Owner string //项目负责人
Phone string //负责人电话
Email string //负责人邮箱
Contact string //项目联系人
ContactPhone string //联系人电话
ContactEmail string //联系人邮箱
ExecuteMonth int //执行周期(月)
ExecuteStartYear int //执行开始年份
ExecuteEndYear int //执行结束年份
ExecutePeriod string //执行期限
Type string //项目类型
StartUp string //启动会时间
NumberTopic int
Topic1 string
Topic2 string
Topic3 string
Topic4 string
Topic5 string
Topic6 string
Topic7 string
AllInstitution string `xorm:"TEXT"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}

func (t *TechConvergeBaseInfo) Brief() *TechConvergeBrief {
return &TechConvergeBrief{
ProjectNumber: t.ProjectNumber,
ProjectName: t.ProjectName,
Institution: t.Institution,
AllInstitution: t.AllInstitution,
}
}
func (t *TechConvergeBaseInfo) IsValidInstitution(institution string) bool {
if t.AllInstitution == "" && t.Institution == "" {
return false
}

allInstitution := make([]string, 0)
if t.AllInstitution != "" {
allInstitution = strings.Split(t.AllInstitution, ",")
}
if t.Institution != "" {
allInstitution = append(allInstitution, t.Institution)
}

newInstitution := strings.Split(institution, ",")
total := len(newInstitution)
matched := 0
for _, n := range newInstitution {
for _, s := range allInstitution {
if s == n {
matched++
break
}
}
}
if matched == total {
return true
}
return false
}

type RepoConvergeInfo struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64
Url string
BaseInfoID int64
Institution string
UID int64
Status int
CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
User *User `xorm:"-"`
Repo *Repository `xorm:"-"`
BaseInfo *TechConvergeBaseInfo `xorm:"-"`
}

func (r *RepoConvergeInfo) InsertOrUpdate() error {
if r.ID != 0 {
_, err := x.ID(r.ID).Update(r)
return err
} else {
_, err := x.InsertOne(r)
return err
}
}

func GetTechConvergeBaseInfoByProjectNumber(projectNumber string) (*TechConvergeBaseInfo, error) {
tb := &TechConvergeBaseInfo{ProjectNumber: projectNumber}
return getTechConvergeBaseInfo(tb)
}

func GetTechConvergeBaseInfoById(id int64) (*TechConvergeBaseInfo, error) {
tb := &TechConvergeBaseInfo{ID: id}
return getTechConvergeBaseInfo(tb)
}

func (baseInfo *TechConvergeBaseInfo) InsertOrUpdate() error {
if baseInfo.ID != 0 {
_, err := x.ID(baseInfo.ID).Update(baseInfo)
return err
} else {
_, err := x.InsertOne(baseInfo)
return err
}
}

type ErrTechConvergeBaseInfoNotExist struct {
ID string
}

func (err ErrTechConvergeBaseInfoNotExist) Error() string {
return "tech.tech_not_exist"
}

func IsErrTechConvergeBaseInfoNotExist(err error) bool {
_, ok := err.(ErrTechConvergeBaseInfoNotExist)
return ok
}

func getTechConvergeBaseInfo(tb *TechConvergeBaseInfo) (*TechConvergeBaseInfo, error) {
has, err := x.Get(tb)
if err != nil {
return nil, err
} else if !has {
if tb.ProjectNumber != "" {
return nil, ErrTechConvergeBaseInfoNotExist{tb.ProjectNumber}
} else {
return nil, ErrTechConvergeBaseInfoNotExist{strconv.FormatInt(tb.ID, 10)}
}
}
return tb, nil
}

func GetProjectNames() []string {
var names []string
x.Table("tech_converge_base_info").Distinct("project_name").Find(&names)
return names
}
func GetIdByProjectName(name string) []string {
var ids []int64
x.Table("tech_converge_base_info").Cols("id").Where("project_name=?", name).Find(&ids)

idStrs := make([]string, 0, len(ids))
for _, id := range ids {
idStrs = append(idStrs, strconv.FormatInt(id, 10))
}
return idStrs
}
func GetSummitRepoIds() []int64 {
var ids []int64
x.Table("repo_converge_info").Cols("repo_id").Find(&ids)
return ids
}

func GetTechRepoTopics(limit int) []string {

repoIds := GetSummitRepoIds()
if len(repoIds) == 0 {
return []string{}
}

//select name, repo_count from topic a, repo_topic b
//where a.id=b.topic_id and repo_id in (1,3) order by repo_count desc
inCondition := "repo_id in ("

const MaxINItems = 1000
for i := 0; i < len(repoIds); i++ {
if i == len(repoIds)-1 {
inCondition += strconv.FormatInt(repoIds[i], 10)
} else if (i+1)%MaxINItems == 0 {
inCondition += strconv.FormatInt(repoIds[i], 10) + ") or repo_id in ("
} else {
inCondition += strconv.FormatInt(repoIds[i], 10) + ","
}

}
inCondition += ")"

sql := "select distinct name, repo_count from topic a, repo_topic b where a.id=b.topic_id and (" + inCondition + ") order by repo_count desc"
if limit > 0 {
sql += "limit " + strconv.Itoa(limit)
}

result, err := x.QueryString(sql)
if err != nil {
return []string{}
}
var topics []string
for _, record := range result {
topics = append(topics, record["name"])
}
return topics

}

func GetProjectTypes() []string {

sql := "SELECT COUNT(id) AS theCount, type from tech_converge_base_info GROUP BY type ORDER BY theCount DESC"
result, err := x.QueryString(sql)
if err != nil {
return []string{}
}
var projectTypes []string
for _, record := range result {
projectTypes = append(projectTypes, record["type"])
}
return projectTypes

}
func GetApplyExecuteYears() ([]int, []int) {
apply, executeStart, executeEnd := GetYearInfos()
applyEnd := time.Now().Year()

var applyArray []int
var executeArray []int

for i := apply; i <= applyEnd; i++ {
applyArray = append(applyArray, i)

}
for i := executeStart; i <= executeEnd; i++ {
executeArray = append(executeArray, i)

}
return applyArray, executeArray
}
func GetYearInfos() (int, int, int) {

sql := "select min(apply_year) as apply_year,min(CASE WHEN execute_start_year != 0 THEN execute_start_year END) as execute_start_year,max(execute_end_year) as execute_end_year from tech_converge_base_info"
result, err := x.QueryString(sql)
if err != nil {
return 2018, 2019, 2024
}

for _, record := range result {
apply, _ := strconv.Atoi(record["apply_year"])
executeStart, _ := strconv.Atoi(record["execute_start_year"])
executeEnd, _ := strconv.Atoi(record["execute_end_year"])
return apply, executeStart, executeEnd
}
return 2018, 2019, 2024
}

func GetAllInstitutions() []string {
var names []string
x.Table("tech_converge_base_info").Cols("all_institution").Find(&names)
var allNames []string
for _, name := range names {
singleNames := strings.Split(name, ",")
for _, singleName := range singleNames {
if singleName != "" {
if !contains(allNames, singleName) {
allNames = append(allNames, singleName)
}
}
}

}
return allNames
}

func contains(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}

type SearchTechOpt struct {
Q string //科技项目名称
ProjectType string
Institution string
ApplyYear int
ExecuteYear int
OrderBy string
ListOptions
}

type SearchRepoOpt struct {
Q string //项目名称,简介
ProjectName string
Topic string
Institution string
OrderBy string
ListOptions
}

type SearchUserRepoOpt struct {
User *User
ListOptions
}

type TechRepoInfoUser struct {
ID int64 `json:"id"`
ProjectNumber string `json:"no"`
ProjectName string `json:"name"`
Institution string `json:"institution"`
AllInstitution string `json:"all_institution"`
Url string `json:"url"`
RepoName string `json:"repo_name"`
RepoOwnerName string `json:"repo_owner_name"`
ContributionInstitution string `json:"contribution_institution"`
UserName string `json:"user_name"`
Status int `json:"status"`
CreatedUnix timeutil.TimeStamp `json:"created_unix"`
UpdatedUnix timeutil.TimeStamp `json:"updated_unix"`
}
type TechRepoInfoAdmin struct {
ID int64 `json:"id"`
Url string `json:"url"`
ContributionInstitution string `json:"contribution_institution"`
Status int `json:"status"`
ProjectNumber string `json:"no"`
ProjectName string `json:"name"`
ApplyYear int `json:"apply_year"`
Institution string `json:"institution"`
Province string `json:"province"`
Category string `json:"category"`
Recommend string `json:"recommend"`
Owner string `json:"owner"`
Phone string `json:"phone"`
Email string `json:"email"`
Contact string `json:"contact"`
ContactPhone string `json:"contact_phone"`
ContactEmail string `json:"contact_email"`
ExecuteMonth int `json:"execute_month"`
ExecutePeriod string `json:"execute_period"`
Type string `json:"type"`
StartUp string `json:"start_up"`
NumberTopic int `json:"number_topic"`
Topic1 string `json:"topic1"`
Topic2 string `json:"topic2"`
Topic3 string `json:"topic3"`
Topic4 string `json:"topic4"`
Topic5 string `json:"topic5"`
AllInstitution string `json:"all_institution"`
RepoName string `json:"repo_name"`
RepoOwnerName string `json:"repo_owner_name"`
UserName string `json:"user_name"`
CreatedUnix timeutil.TimeStamp `json:"created_unix"`
UpdatedUnix timeutil.TimeStamp `json:"updated_unix"`
}

type RepoWithInstitution struct {
ID int64 `json:"id"`
OwnerID int64 `json:"owner_id"`
OwnerName string `json:"owner_name"`
Name string `json:"name"`
Alias string `json:"alias"`
Topics []string `json:"topics"`
Description string `json:"description"`
Institution string `json:"institution"`
RelAvatarLink string `json:"rel_avatar_link"`
UpdatedUnix timeutil.TimeStamp `json:"updated_unix"`
}

type TechRepoInfo struct {
ID int64 `json:"id"`
ProjectName string `json:"project_name"`
Institution string `json:"institution"`
Type string `json:"type"`
ApplyYear int `json:"apply_year"`
ExecutePeriod string `json:"execute_period"`
AllInstitution string `json:"all_institution"`
RepoCount int `json:"repo_numer"`
Repos []*RepoWithInstitution
}

func ShowTechRepo(ids []int64, show bool) error {

status := TechShow
if !show {
status = TechHide
}

idStrs := make([]string, 0, len(ids))
for _, id := range ids {
idStrs = append(idStrs, strconv.FormatInt(id, 10))
}

sql := "update repo_converge_info set status=? where id in (" + strings.Join(idStrs, ",") + ") and (status=" + strconv.Itoa(TechShow) + " or status=" + strconv.Itoa(TechHide) + ")"
_, err := x.Exec(sql, status)
return err
}

func GetTechRepoInfoForUser(opts *SearchUserRepoOpt) ([]*RepoConvergeInfo, int64, error) {
cond := buildTechRepoForUserCondition(opts)
total, err := x.Where(cond).Count(new(RepoConvergeInfo))
if err != nil {
return nil, 0, err
}
repoConvergeInfos := make([]*RepoConvergeInfo, 0)
err = x.Where(cond).Limit(opts.PageSize, (opts.Page-1)*opts.PageSize).Desc("status").Find(&repoConvergeInfos)
if err != nil {
return nil, 0, err
}

loadAttributes(repoConvergeInfos)

return repoConvergeInfos, total, nil

}

func loadAttributes(infos []*RepoConvergeInfo) {
for _, info := range infos {
info.User, _ = GetUserByID(info.UID)
info.Repo, _ = GetRepositoryByID(info.RepoID)
info.BaseInfo, _ = GetTechConvergeBaseInfoById(info.BaseInfoID)
}
}

func buildTechRepoForUserCondition(opts *SearchUserRepoOpt) builder.Cond {
var cond = builder.NewCond()
if opts.User != nil {
cond = cond.And(builder.Eq{"uid": opts.User.ID})
}
return cond
}

func GetAvailableRepoConvergeInfo(opt *SearchRepoOpt) ([]*RepoConvergeInfo, error) {

repos := make([]*RepoConvergeInfo, 0)
err := x.Table("repo_converge_info").Where(buildRepoFilterCond(opt)).Find(&repos)
return repos, err

}

func buildRepoFilterCond(opt *SearchRepoOpt) string {

sql := "status=" + strconv.Itoa(TechShow)

if opt.Institution != "" {
sql += " and (institution like '%" + opt.Institution + ",%'" + " or institution like '%," + opt.Institution + "%'" + " or institution = '" + opt.Institution + "')"
}

if opt.ProjectName != "" {
baseInfoIds := GetIdByProjectName(opt.ProjectName)
if len(baseInfoIds) > 0 {

sql += " and base_info_id in (" + strings.Join(baseInfoIds, ",") + ")"
}

}
return sql
}

func SearchTechRepoInfo(opt *SearchTechOpt) ([]*TechRepoInfo, int64, error) {

sql := `select a.*,COALESCE(b.count,0) as repo_count, COALESCE(b.max,0) as max from tech_converge_base_info a left join
(select base_info_id,count(id),max(updated_unix) from repo_converge_info where status=` + strconv.Itoa(TechShow) + ` GROUP BY base_info_id ) b
on a.id=b.base_info_id`
totalSql := "select count(*) from (" + sql + ") c" + buildTechFilterCond(opt)
total, err := x.SQL(totalSql).Count(new(TechConvergeBaseInfo))
resultList := make([]*TechRepoInfo, 0)
if err != nil {
return resultList, total, err

}
resultSql := "select id,project_name, institution,type,apply_year,execute_period,all_institution,repo_count from (" +
sql + ") c " + buildTechFilterCond(opt) + opt.OrderBy + " offset " + strconv.Itoa((opt.Page-1)*opt.PageSize) + " limit " + strconv.Itoa(opt.PageSize)

resultMap, err := x.QueryInterface(resultSql)
if err == nil {
for _, record := range resultMap {
resultList = append(resultList, &TechRepoInfo{
ID: record["id"].(int64),
ProjectName: record["project_name"].(string),
Institution: record["institution"].(string),
Type: record["type"].(string),
ApplyYear: int(record["apply_year"].(int64)),
ExecutePeriod: record["execute_period"].(string),
AllInstitution: record["all_institution"].(string),
RepoCount: int(record["repo_count"].(int64)),
})
}
}

loadRepoInfoForTech(resultList)

return resultList, total, err

}

func buildTechFilterCond(opt *SearchTechOpt) string {

sql := ""

if opt.Q != "" {
sql += getWherePrefix(sql) + " project_name like '%" + opt.Q + "%'"

}
if opt.ProjectType != "" {
sql += getWherePrefix(sql) + " type ='" + opt.ProjectType + "'"
}
if opt.ApplyYear != 0 {
sql += getWherePrefix(sql) + " apply_year =" + strconv.Itoa(opt.ApplyYear)
}
if opt.Institution != "" {
sql += getWherePrefix(sql) + " (all_institution like '%" + opt.Institution + ",%'" + " or all_institution like '%," + opt.Institution + "%'" + " or all_institution = '" + opt.Institution + "')"
}

if opt.ExecuteYear != 0 {
sql += getWherePrefix(sql) + " execute_start_year <=" + strconv.Itoa(opt.ExecuteYear) + " and execute_end_year >=" + strconv.Itoa(opt.ExecuteYear)
}
return sql
}

func getWherePrefix(sql string) string {
if sql == "" {
return " where "
}
return " and "
}

func loadRepoInfoForTech(list []*TechRepoInfo) {

for _, techRepo := range list {
techRepo.Repos = []*RepoWithInstitution{}
if techRepo.RepoCount > 0 {
var repoIds []int64
x.Table("repo_converge_info").Cols("repo_id").Where("base_info_id=? and status=?", techRepo.ID, TechShow).Limit(2).Desc("updated_unix").Find(&repoIds)

resultMap, err := GetRepositoriesMapByIDs(repoIds)

if err == nil {

for _, repoId := range repoIds {
repo, ok := resultMap[repoId]
if ok {
techRepo.Repos = append(techRepo.Repos, &RepoWithInstitution{
ID: repo.ID,
Institution: techRepo.Institution,
OwnerID: repo.OwnerID,
OwnerName: repo.OwnerName,
Name: repo.Name,
Alias: repo.Alias,
Topics: repo.Topics,
Description: repo.Description,
RelAvatarLink: repo.RelAvatarLink(),
UpdatedUnix: repo.UpdatedUnix,
})
}

}

}
}
}

}

type TechConvergeBrief struct {
ProjectNumber string `json:"no"` //项目立项编号
ProjectName string `json:"name"` //科技项目名称
Institution string `json:"institution"` //项目承担单位
AllInstitution string `json:"all_institution"`
}

type FindTechOpt struct {
TechNo string
ProjectName string
Institution string
}

func FindTech(opt FindTechOpt) ([]*TechConvergeBaseInfo, error) {
var cond = builder.NewCond()
if opt.TechNo != "" {
cond = cond.And(builder.Like{"project_number", opt.TechNo})
}
if opt.ProjectName != "" {
cond = cond.And(builder.Like{"project_name", opt.ProjectName})
}
if opt.Institution != "" {
cond = cond.And(builder.Like{"institution", opt.Institution}.Or(builder.Like{"all_institution", opt.Institution}))
}

r := make([]*TechConvergeBaseInfo, 0)
err := x.Where(cond).OrderBy("updated_unix desc").Find(&r)
if err != nil {
return nil, err
}
return r, nil
}

func GetTechByTechNo(techNo string) (*TechConvergeBaseInfo, error) {
var tech = &TechConvergeBaseInfo{}
has, err := x.Where("project_number = ?", techNo).Get(tech)
if err != nil {
return nil, err
} else if !has {
return nil, ErrTechConvergeBaseInfoNotExist{}
}
return tech, nil

}

type GetRepoConvergeOpts struct {
RepoId int64
BaseInfoId int64
Status []int
}

func GetRepoConverge(opts GetRepoConvergeOpts) ([]*RepoConvergeInfo, error) {
r := make([]*RepoConvergeInfo, 0)
cond := builder.NewCond()
if opts.RepoId > 0 {
cond = cond.And(builder.Eq{"repo_id": opts.RepoId})
}
if opts.BaseInfoId > 0 {
cond = cond.And(builder.Eq{"base_info_id": opts.BaseInfoId})
}
if len(opts.Status) > 0 {
cond = cond.And(builder.In("status", opts.Status))
}
err := x.Where(cond).Find(&r)
if err != nil {
return nil, err
}
return r, nil

}

func UpdateRepoConvergeStatus(id int64, status int) (int64, error) {
return x.ID(id).Update(&RepoConvergeInfo{
Status: status,
})
}

+ 2
- 2
modules/auth/user_form.go View File

@@ -82,7 +82,7 @@ type RegisterForm struct {
Email string `binding:"Required;Email;MaxSize(254)"`
Password string `binding:"MaxSize(255)"`
PhoneNumber string `binding:"MaxSize(20)"`
VerifyCode string `binding:"MaxSize(10)"`
VerifyCode string
Retype string
GRecaptchaResponse string `form:"g-recaptcha-response"`
Agree bool
@@ -386,7 +386,7 @@ func (f *PhoneNumberForm) Validate(ctx *macaron.Context, errs binding.Errors) bi

type PhoneNumberCodeForm struct {
PhoneNumber string `binding:"Required;MaxSize(20)"`
VerifyCode string `binding:"Required;MaxSize(10)"`
VerifyCode string `binding:"Required;"`
Remember bool
}



+ 6
- 1
modules/auth/wechat/cloudbrain.go View File

@@ -105,6 +105,7 @@ func (CloudbrainStopMsg) TemplateId(ctx *TemplateContext) string {

var startMsg = &CloudbrainStartMsg{}
var stopMsg = &CloudbrainStopMsg{}
var ComingStopMsg = &CloudbrainComingToStopMsg{}

func GetTemplateFromOperateType(operate JobOperateType) Template {
switch operate {
@@ -160,7 +161,11 @@ func getJobTypeDisplayName(jobType string) string {
return "评测任务"
case string(models.JobTypeTrain):
return "训练任务"
case string(models.JobTypeInference):
case string(models.JobTypeInference),
string(models.JobTypeModelSafety),
string(models.JobTypeSnn4imagenet),
string(models.JobTypeBrainScore),
string(models.JobTypeSnn4Ecoset):
return "推理任务"
}
return ""


+ 48
- 0
modules/auth/wechat/point.go View File

@@ -0,0 +1,48 @@
package wechat

import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"fmt"
"time"
)

type CloudbrainComingToStopMsg struct {
}

func (CloudbrainComingToStopMsg) Data(ctx *TemplateContext) *DefaultWechatTemplate {
var balance int64
if ctx.PointAccount != nil {
balance = ctx.PointAccount.Balance
}
return &DefaultWechatTemplate{
First: TemplateValue{Value: setting.CloudbrainComingStopTitle},
Keyword1: TemplateValue{Value: ctx.Cloudbrain.DisplayJobName + "(任务名称)"},
Keyword2: TemplateValue{Value: fmt.Sprintf("%d积分", balance)},
Keyword3: TemplateValue{Value: setting.CloudbrainComingStopChargeLink},
Keyword4: TemplateValue{Value: time.Unix(int64(ctx.EstimatedEndTime), 0).Format("2006-01-02 15:04:05") + "(预计停止时间)"},
Remark: TemplateValue{Value: setting.CloudbrainComingStopRemark},
}
}

func (CloudbrainComingToStopMsg) ShouldSend(ctx *TemplateContext) bool {
return setting.CloudbrainComingStopSendFlag
}

func (CloudbrainComingToStopMsg) MsgId(ctx *TemplateContext) string {
return "coming_stop_" + fmt.Sprint(ctx.Cloudbrain.ID) + "_" + fmt.Sprint(time.Now().Unix())
}

func (CloudbrainComingToStopMsg) Url(ctx *TemplateContext) string {
repo, err := models.GetRepositoryByID(ctx.Cloudbrain.RepoID)
if err != nil {
log.Error("CloudbrainComingToStopMsg GetRepositoryByID error,%v", err)
return ""
}
return getCloudbrainTemplateUrl(*ctx.Cloudbrain, repo)
}

func (CloudbrainComingToStopMsg) TemplateId(ctx *TemplateContext) string {
return setting.CloudbrainComingStopTemplateId
}

+ 11
- 6
modules/auth/wechat/template.go View File

@@ -3,6 +3,7 @@ package wechat
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/timeutil"
"errors"
"fmt"
)
@@ -16,7 +17,9 @@ type Template interface {
}

type TemplateContext struct {
Cloudbrain *models.Cloudbrain
Cloudbrain *models.Cloudbrain
EstimatedEndTime timeutil.TimeStamp
PointAccount *models.PointAccount
}

func SendTemplateMsg(template Template, ctx *TemplateContext, userId int64) error {
@@ -36,28 +39,30 @@ func SendTemplateMsg(template Template, ctx *TemplateContext, userId int64) erro
log.Error("Wechat openId not exist,userId=%d", userId)
return errors.New("Wechat openId not exist")
}
d := template.Data(ctx)
req := TemplateMsgRequest{
ToUser: openId,
TemplateId: template.TemplateId(ctx),
Url: template.Url(ctx),
ClientMsgId: template.MsgId(ctx),
Data: template.Data(ctx),
Data: d,
}
log.Info("SendTemplateMsg before calling.userId = %d,req=%v data=%v", userId, req, *d)
err, retryFlag := sendTemplateMsg(req)
if retryFlag {
log.Info("SendTemplateMsg calling")
log.Info("SendTemplateMsg calling.userId = %d", userId)
refreshAccessToken()
err, _ = sendTemplateMsg(req)
if err != nil {
log.Error("SendTemplateMsg err. %v", err)
log.Error("SendTemplateMsg userId = %d err. %v", userId, err)
return err
}
return nil
}
if err != nil {
log.Error("SendTemplateMsg err. %v", err)
log.Error("SendTemplateMsg userId = %d err. %v", userId, err)
return err
}
log.Info("SendTemplateMsg success")
log.Info("SendTemplateMsg success userId = %d", userId)
return nil
}

+ 217
- 0
modules/base/tool.go View File

@@ -421,3 +421,220 @@ func SetupGiteaRoot() string {
}
return giteaRoot
}

// JudgeLanguageBySuffix get language from fileName
func JudgeLanguageBySuffix(filename string) string {
if len(filename) == 0 {
return "shell"
}
arr := strings.Split(filename, ".")
suffix := strings.ToLower(arr[len(arr)-1])
suffixLanguageMap := map[string]string{
"py": "python",
"c": "cpp",
"h": "cpp",
"g4": "cpp",
"sy": "cpp",
"cc": "cpp",
"cxx": "cpp",
"c++": "cpp",
"cu": "cpp",
"cpp": "cpp",
"dynamips": "cpp",
"java": "java",
"php": "php",
"html": "html",
"css": "css",
"scss": "scss",
"go": "go",
"r": "r",
"graphql": "graphql",
"swift": "swift",
"xml": "xml",
"yaml": "yaml",
"json": "json",
"lua": "lua",
"scheme": "scheme",
"less": "less",
"ini": "ini",
"jpg": "jpg",
"jpeg": "jpeg",
"png": "png",
"gif": "gif",
"webp": "webp",
"bmp": "bmp",
"avi": "avi",
"mp4": "mp4",
"mov": "mov",
"mp3": "mp3",
"wav": "wav",
"ogg": "ogg",
"coffee": "coffeescript",
"litcoffee": "coffeescript",
"js": "javascript",
"vue": "javascript",
"ejs": "html",
"cs": "csharp",
"kt": "kotlin",
"md": "markdown",
"sql": "mysql",
"ctrl": "mysql",
"m": "objective-c",
"mm": "objective-c",
"pas": "pascal",
"perl": "perl",
"pl": "perl",
"rb": "ruby",
"rs": "rust", "rust": "rust",
"tsx": "typescript",
"ipynb": "json",
"sh": "shell",
"bash": "shell",
}

if suffixLanguageMap[suffix] == "" {
return "shell"
} else {
return suffixLanguageMap[suffix]
}

}

// JudgeFileTypeBySuffix get language from fileName
func JudgeFileTypeBySuffix(filename string) string {
if len(filename) == 0 {
return "other"
}
arr := strings.Split(filename, ".")
suffix := strings.ToLower(arr[len(arr)-1])
suffixFileTypeMap := map[string]string{
"py": "txt",
"h": "txt",
"c": "txt",
"cpp": "txt",
"cc": "txt",
"java": "txt",
"php": "txt",
"html": "txt",
"css": "txt",
"scss": "txt",
"go": "txt",
"r": "txt",
"graphql": "txt",
"swift": "txt",
"xml": "txt",
"yaml": "txt",
"json": "txt",
"lua": "txt",
"scheme": "txt",
"less": "txt",
"ini": "txt",
"coffee": "txt",
"litcoffee": "txt",
"js": "txt",
"cs": "txt",
"kt": "txt",
"md": "txt",
"sql": "txt",
"m": "txt",
"mm": "txt",
"pas": "txt",
"perl": "txt",
"ejs": "txt",
"pl": "txt",
"rb": "txt",
"rs": "txt",
"rust": "txt",
"sh": "txt",
"makefile": "txt",
"circ": "txt",
"readme": "txt",
"yml": "txt",
"sml": "txt",
"conf": "txt",
"txt": "txt",
"gitignore": "txt",
"in": "txt",
"cu": "txt",
"gemfile": "txt",
"scala": "txt",
"net": "txt",
"l": "txt",
"v": "txt",
"config": "txt",
"properties": "txt",
"log": "txt",
"htm": "txt",
"cnf": "txt",
"hex": "txt",
"bat": "txt",
"asm": "txt",
"bash": "txt",
"ts": "txt",
"tsx": "txt",
"sass": "txt",
"jsx": "txt",
"jsp": "txt",
"gitkeep": "txt",
"sv": "txt",
"hql": "txt",
"y": "txt",
"jj": "txt",
"pls": "txt",
"sol": "txt",
"ignore": "txt",
"ctrl": "txt",
"vue": "txt",
"tex": "txt",
"bib": "txt",
"cls": "txt",
"bst": "txt",
"toc": "txt",
"sty": "txt",
"g4": "txt",
"sy": "txt",
"jpg": "image",
"jpeg": "image",
"png": "image",
"gif": "image",
"webp": "image",
"bmp": "image",
"avi": "video",
"mp4": "video",
"mov": "video",
"mp3": "audio",
"wav": "audio",
"ogg": "audio",
"pptm": "office",
"pptx": "office",
"ppt": "office",
"pot": "office",
"pps": "office",
"ppa": "office",
"potx": "office",
"ppsx": "office",
"ppam": "office",
"potm": "office",
"ppsm": "office",
"doc": "office",
"docx": "office",
"dot": "office",
"dotx": "office",
"docm": "office",
"dotm": "office",
"xls": "office",
"xlsx": "office",
"csv": "office",
"xlt": "office",
"xla": "office",
"xltx": "office",
"xlsm": "office",
"xltm": "office",
"xlam": "office",
"xlsb": "office",
"pdf": "pdf",
"ipynb": "ipynb",
}

return suffixFileTypeMap[suffix]
}

+ 2
- 6
modules/cloudbrain/cloudbrain.go View File

@@ -35,6 +35,7 @@ const (
Snn4imagenetCommand = `/opt/conda/bin/python /benchmark/testSNN_script.py --modelname '%s' --modelpath '/pretrainmodel/%s' --modeldescription '%s' >/model/benchmark-log.txt`
BrainScoreCommand = `bash /benchmark/brainscore_test_par4shSrcipt.sh -b '%s' -n '%s' -p '/pretrainmodel/%s' -d '%s' >/model/benchmark-log.txt`
Snn4EcosetCommand = `/opt/conda/bin/python /benchmark/testSNN_script.py --datapath '/dataset' --modelname '%s' --modelpath '/pretrainmodel/%s' --modeldescription '%s' >/model/benchmark-log.txt`
Sim2BrianSnnCommand = `cd /code && /opt/conda/bin/python /benchmark/score_a_model.py --benchmark '%s' --dataset-path '/dataset' --metric 'RSA' --model-name '%s' --model-checkpoint '/pretrainmodel/%s' --model-description '%s' >/model/benchmark-log.txt`
SubTaskName = "task1"

Success = "S000"
@@ -378,7 +379,7 @@ func GenerateTask(req GenerateCloudBrainTaskReq) (string, error) {

stringId := strconv.FormatInt(task.ID, 10)

if IsBenchmarkJob(req.JobType) {
if models.IsBenchMarkJobType(req.JobType) {
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, stringId, req.DisplayJobName, models.ActionCreateBenchMarkTask)
} else if string(models.JobTypeTrain) == req.JobType {
notification.NotifyOtherTask(req.Ctx.User, req.Ctx.Repo.Repository, jobID, req.DisplayJobName, models.ActionCreateGPUTrainTask)
@@ -391,10 +392,6 @@ func GenerateTask(req GenerateCloudBrainTaskReq) (string, error) {
return jobID, nil
}

func IsBenchmarkJob(jobType string) bool {
return string(models.JobTypeModelSafety) == jobType || string(models.JobTypeBenchmark) == jobType || string(models.JobTypeBrainScore) == jobType || string(models.JobTypeSnn4imagenet) == jobType || string(models.JobTypeSnn4Ecoset) == jobType
}

func GetWaitingCloudbrainCount(cloudbrainType int, computeResource string, jobTypes ...models.JobType) int64 {
num, err := models.GetWaitingCloudbrainCount(cloudbrainType, computeResource, jobTypes...)
if err != nil {
@@ -661,7 +658,6 @@ func IsElementExist(s []string, str string) bool {
return false
}


func GetCloudBrainByIdOrJobId(id string, initialQuery string) (*models.Cloudbrain, error) {
_, err := strconv.ParseInt(id, 10, 64)
var job *models.Cloudbrain


+ 1
- 1
modules/cron/tasks_basic.go View File

@@ -231,7 +231,7 @@ func registerSyncCloudbrainStatus() {
RegisterTaskFatal("sync_cloudbrain_status", &BaseConfig{
Enabled: true,
RunAtStart: false,
Schedule: "@every 10m",
Schedule: setting.SyncCloudbrainStatusDuration,
}, func(ctx context.Context, _ *models.User, _ Config) error {
repo.SyncCloudbrainStatus()
return nil


+ 80
- 0
modules/modelappservice/modelsevice.go View File

@@ -0,0 +1,80 @@
package modelappservice

import (
"bytes"
"fmt"
"runtime"
"strconv"
"strings"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/modelarts"
"code.gitea.io/gitea/modules/setting"
)

var wenxinChannel = make(chan *models.ModelApp, 10000)

func Init() {
urls := setting.BaiduWenXin.ModelArtsWenXinURL
urlarray := strings.Split(urls, ",")
urlNums := len(urlarray)
log.Info("url nums=" + fmt.Sprint(urlNums))
for i := 0; i < setting.BaiduWenXin.RUN_WORKERS; i++ {
go consumerOrder(wenxinChannel, urlarray[i%urlNums])
}
}

func ProducerOrder(modelApp *models.ModelApp) {
wenxinChannel <- modelApp
}

func GetWaitTime() int {
dvid := setting.BaiduWenXin.MODEL_SERVERS
return ((len(wenxinChannel) / dvid) + 1) * 15
}

func consumerOrder(in <-chan *models.ModelApp, url string) {
goroutine_id := GetGid()
log.Info("goroutine id=" + fmt.Sprint(goroutine_id) + "consumer order start...")
for modelApp := range in {
if !modelarts.SendTextReview(modelApp.Desc) {
modelApp.Status = -1
modelApp.Picture = "文本内容可能包括敏感关键字,请重新输入。"
models.UpdateModelApp(modelApp)
continue
}
log.Info("goroutine id=" + fmt.Sprint(goroutine_id) + " wenxin text=" + modelApp.Desc)
result, err := modelarts.CreateWenXinJob(modelApp, url)
if err == nil {
if !modelarts.SendPictureReivew(result.Result) {
modelApp.Status = -1
modelApp.Picture = "生成的图像内容不合法,请重新输入关键字信息。"
models.UpdateModelApp(modelApp)
} else {
modelApp.Status = 0
modelApp.Picture = result.Result
models.UpdateModelApp(modelApp)
}
} else {
log.Info("err=" + err.Error())
modelApp.Status = -1
modelApp.Picture = "哇哦,服务暂时开小差了,请尝试重新生成。"
models.UpdateModelApp(modelApp)
}
}
log.Info("consumer order end...")
}

func GetGid() (gid uint64) {
b := make([]byte, 64)
b = b[:runtime.Stack(b, false)]
b = bytes.TrimPrefix(b, []byte("goroutine "))
b = b[:bytes.IndexByte(b, ' ')]
n, err := strconv.ParseUint(string(b), 10, 64)
if err != nil {
return 0
//panic(err)
}
return n
}

+ 1
- 1
modules/modelarts/modelarts.go View File

@@ -234,7 +234,7 @@ func GenerateNotebook2(ctx *context.Context, req cloudbrain.GenerateModelArtsNot
ComputeResource: models.NPUResource,
Image: imageName,
BootFile: req.BootFile,
BranchName: req.BranchName,
BranchName: req.BranchName,
Description: req.Description,
CreatedUnix: createTime,
UpdatedUnix: createTime,


+ 5
- 0
modules/modelarts/resty.go View File

@@ -1487,3 +1487,8 @@ sendjob:

return &result, nil
}

func ProducePicture() {
//https://modelarts-inference.cloudbrain2.pcl.ac.cn/v1/infers/ba901d47-25bf-4385-8d89-e3a311b85d40

}

+ 231
- 0
modules/modelarts/wenxinresty.go View File

@@ -0,0 +1,231 @@
package modelarts

import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"sync"
"time"

"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)

type CreateWenXinParams struct {
Data WenXinText `json:"data"`
Parameters map[string]string `json:"parameters"`
}

type WenXinText struct {
Prompt string `json:"prompt"`
}

type WenXinResult struct {
Result string `json:"result"`
}

func CreateWenXinJob(modelapp *models.ModelApp, url string) (*WenXinResult, error) {
createJobParams := &CreateWenXinParams{
Data: WenXinText{
Prompt: modelapp.Desc,
},
Parameters: make(map[string]string),
}
checkSetting()
client := getRestyClient()
var result WenXinResult

retry := 0

sendjob:
log.Info("token=" + TOKEN + " url=" + url)
res, err := client.R().
SetHeader("Content-Type", "application/json").
SetHeader("X-Auth-Token", TOKEN).
SetAuthToken(TOKEN).
SetBody(createJobParams).
SetResult(&result).
Post(url)

if err != nil {
return nil, fmt.Errorf("resty CreateWenXinJob: %s", err)
}
log.Info("re status=" + res.Status())
if res.StatusCode() == http.StatusUnauthorized && retry < 1 {
retry++
_ = getToken()
goto sendjob
}
if res.StatusCode() == 200 {
var response WenXinResult
err = json.Unmarshal(res.Body(), &response)
if err != nil {
log.Error("json.Unmarshal failed: %s", err.Error())
return &result, fmt.Errorf("son.Unmarshal failed: %s", err.Error())
}
return &result, nil
} else {
return nil, fmt.Errorf("Service unavailable")
}
}

var expire_time int64
var baidu_token string

func SendPictureReivew(picture_base64 string) bool {
weburl := setting.BaiduWenXin.PICTURE_BAIDU_REVIEW_URL + GetBaiDuAccessToken()
picture_base64 = url.QueryEscape(picture_base64)
// image 可以通过 GetFileContentAsBase64("C:\fakepath\框图.jpg") 方法获取
payload := strings.NewReader("image=" + picture_base64)
client := &http.Client{}
req, err := http.NewRequest("POST", weburl, payload)

if err != nil {
fmt.Println(err)
return false
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Accept", "application/json")

res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return false
}
defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return false
}
bodystr := string(body)
log.Info("img bodystr=" + bodystr)
if strings.Index(bodystr, "\"conclusionType\": 1") > 0 || strings.Index(bodystr, "\"conclusionType\":1") > 0 {
return true
}
if strings.Index(bodystr, "\"error_code\": 18") > 0 || strings.Index(bodystr, "\"error_code\":18") > 0 {
return true
}
return false
}

/**
* 获取文件base64编码
* @param string path 文件路径
* @return string base64编码信息,不带文件头
*/
func GetFileContentAsBase64(path string) string {
srcByte, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println(err)
return ""
}
return base64.StdEncoding.EncodeToString(srcByte)
}

var lock sync.Mutex
var textCache = make(map[string]bool, 2000)

func SendTextReview(text string) bool {
if textCache[text] {
return true
}
bodystr := sendTextReviewToBaidu(text)
log.Info("text bodystr=" + bodystr)
if strings.Index(bodystr, "\"conclusionType\": 1") > 0 || strings.Index(bodystr, "\"conclusionType\":1") > 0 {
setCacheTrue(text, true)
return true
}
if strings.Index(bodystr, "\"error_code\": 18") > 0 || strings.Index(bodystr, "\"error_code\":18") > 0 {
for i := 1; i <= 3; i++ {
log.Info("sleep seconds " + fmt.Sprint(i))
time.Sleep(time.Duration(i) * time.Second)
bodystr := sendTextReviewToBaidu(text)
log.Info("text bodystr=" + bodystr)
if strings.Index(bodystr, "\"conclusionType\": 1") > 0 || strings.Index(bodystr, "\"conclusionType\":1") > 0 {
setCacheTrue(text, true)
return true
}
}
}
setCacheTrue(text, false)
return false
}

func setCacheTrue(text string, isRight bool) {
lock.Lock()
defer lock.Unlock()
if len(textCache) >= 1500 {
for k := range textCache {
delete(textCache, k) //delete only one
break
}
}
textCache[text] = isRight
}

func sendTextReviewToBaidu(text string) string {
url := setting.BaiduWenXin.TEXT_BAIDU_REVIEW_URL + GetBaiDuAccessToken()
payload := strings.NewReader("text=" + text)
client := &http.Client{}
req, err := http.NewRequest("POST", url, payload)

if err != nil {
fmt.Println(err)
return ""
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
req.Header.Add("Accept", "application/json")

res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return ""
}
defer res.Body.Close()

body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return ""
}
bodystr := string(body)
return bodystr
}

/**
* 使用 AK,SK 生成鉴权签名(Access Token)
* @return string 鉴权签名信息(Access Token)
*/
func GetBaiDuAccessToken() string {
if baidu_token != "" {
if time.Now().Unix()-expire_time < 20*24*3600 {
return baidu_token
}
}

url := setting.BaiduWenXin.BAIDU_TOKEN_URL
postData := fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", setting.BaiduWenXin.BAIDU_API_KEY, setting.BaiduWenXin.BAIDU_SECRET_KEY)
resp, err := http.Post(url, "application/x-www-form-urlencoded", strings.NewReader(postData))
if err != nil {
fmt.Println(err)
return ""
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return ""
}
accessTokenObj := map[string]string{}
json.Unmarshal([]byte(body), &accessTokenObj)
baidu_token = accessTokenObj["access_token"]
expire_time = time.Now().Unix()
return accessTokenObj["access_token"]
}

+ 2
- 0
modules/notification/base/notifier.go View File

@@ -8,6 +8,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/timeutil"
)

// Notifier defines an interface to notify receiver
@@ -64,4 +65,5 @@ type Notifier interface {
NotifyChangeUserAvatar(user *models.User, form auth.AvatarForm)

NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string)
NotifyCloudbrainTaskComingToFinished(cloudbrain *models.Cloudbrain, endTime timeutil.TimeStamp, account *models.PointAccount)
}

+ 5
- 0
modules/notification/base/null.go View File

@@ -8,6 +8,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/auth"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/timeutil"
)

// NullNotifier implements a blank notifier
@@ -180,3 +181,7 @@ func (*NullNotifier) NotifyChangeUserAvatar(user *models.User, form auth.AvatarF
func (*NullNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus string) {

}

func (*NullNotifier) NotifyCloudbrainTaskComingToFinished(cloudbrain *models.Cloudbrain, endTime timeutil.TimeStamp, account *models.PointAccount) {

}

+ 8
- 0
modules/notification/notification.go View File

@@ -17,6 +17,7 @@ import (
wechatNotifier "code.gitea.io/gitea/modules/notification/wechat"
"code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
)

var (
@@ -316,3 +317,10 @@ func NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrain, oldStatus strin
notifier.NotifyChangeCloudbrainStatus(cloudbrain, oldStatus)
}
}

// NotifyCloudbrainTaskComingToFinished
func NotifyCloudbrainTaskComingToFinished(cloudbrain *models.Cloudbrain, estimatedEndTime timeutil.TimeStamp, account *models.PointAccount) {
for _, notifier := range notifiers {
notifier.NotifyCloudbrainTaskComingToFinished(cloudbrain, estimatedEndTime, account)
}
}

+ 7
- 0
modules/notification/wechat/wechat.go View File

@@ -9,6 +9,7 @@ import (
"code.gitea.io/gitea/modules/auth/wechat"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification/base"
"code.gitea.io/gitea/modules/timeutil"
)

type wechatNotifier struct {
@@ -34,3 +35,9 @@ func (*wechatNotifier) NotifyChangeCloudbrainStatus(cloudbrain *models.Cloudbrai
template := wechat.GetTemplateFromOperateType(operateType)
go wechat.SendTemplateMsg(template, &wechat.TemplateContext{Cloudbrain: cloudbrain}, cloudbrain.UserID)
}

func (*wechatNotifier) NotifyCloudbrainTaskComingToFinished(cloudbrain *models.Cloudbrain, endTime timeutil.TimeStamp, account *models.PointAccount) {
log.Info("NotifyCloudbrainTaskComingToFinished cloudbrain.id=%d", cloudbrain.ID)
template := wechat.ComingStopMsg
go wechat.SendTemplateMsg(template, &wechat.TemplateContext{Cloudbrain: cloudbrain, EstimatedEndTime: endTime, PointAccount: account}, cloudbrain.UserID)
}

+ 4
- 0
modules/redis/redis_key/reward_redis_key.go View File

@@ -19,3 +19,7 @@ func RewardOperateNotification() string {
func RewardTaskRunningLock(taskId int64) string {
return KeyJoin(REWARD_REDIS_PREFIX, "periodic_task", fmt.Sprint(taskId), "lock")
}

func RewardMsgNewestTime(userId int64, msgType string, code string) string {
return KeyJoin(REWARD_REDIS_PREFIX, "msg", fmt.Sprint(userId), msgType, code, "newest_time")
}

+ 33
- 8
modules/repofiles/content.go View File

@@ -5,7 +5,10 @@
package repofiles

import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/log"
"fmt"
"io"
"net/url"
"path"
"strings"
@@ -95,6 +98,7 @@ func GetContentsOrList(repo *models.Repository, treePath, ref string) (interface
}
fileList = append(fileList, fileContentResponse)
}

return fileList, nil
}

@@ -187,16 +191,14 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
contentsResponse.SubmoduleGitURL = &submodule.URL
}
// Handle links
if entry.IsRegular() || entry.IsLink() {
downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
if err != nil {
return nil, err
}
downloadURLString := downloadURL.String()
contentsResponse.DownloadURL = &downloadURLString
downloadURL, err := url.Parse(fmt.Sprintf("%s/raw/%s/%s/%s", repo.HTMLURL(), refType, url.QueryEscape(ref), treePath))
if err != nil {
return nil, err
}
downloadURLString := downloadURL.String()
contentsResponse.DownloadURL = &downloadURLString
if !entry.IsSubModule() {
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, ref, treePath))
htmlURL, err := url.Parse(fmt.Sprintf("%s/src/%s/%s/%s", repo.HTMLURL(), refType, url.QueryEscape(ref), treePath))
if err != nil {
return nil, err
}
@@ -213,5 +215,28 @@ func GetContents(repo *models.Repository, treePath, ref string, forList bool) (*
contentsResponse.Links.GitURL = &gitURLString
}

// set file language and file type
contentsResponse.Language = base.JudgeLanguageBySuffix(treePath)
var fileType = base.JudgeFileTypeBySuffix(treePath)
if fileType == "" {
blob := entry.Blob()
dataRc, _ := blob.DataAsync()
defer func(dataRc io.ReadCloser) {
err := dataRc.Close()
if err != nil {
log.Error("DataAsync", err)
}
}(dataRc)
buf := make([]byte, 1024)
n, _ := dataRc.Read(buf)
buf = buf[:n]
if base.IsTextFile(buf) {
fileType = "txt"
} else {
fileType = "other"
}
}
contentsResponse.FileType = fileType

return contentsResponse, nil
}

+ 6
- 2
modules/repofiles/tree.go View File

@@ -14,7 +14,7 @@ import (
)

// GetTreeBySHA get the GitTreeResponse of a repository using a sha hash.
func GetTreeBySHA(repo *models.Repository, sha string, page, perPage int, recursive bool) (*api.GitTreeResponse, error) {
func GetTreeBySHA(repo *models.Repository, sha string, page, perPage int, recursive bool, truncate bool) (*api.GitTreeResponse, error) {
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
return nil, err
@@ -55,7 +55,11 @@ func GetTreeBySHA(repo *models.Repository, sha string, page, perPage int, recurs
copyPos := len(treeURL) - 40

if perPage <= 0 || perPage > setting.API.DefaultGitTreesPerPage {
perPage = setting.API.DefaultGitTreesPerPage
if truncate {
perPage = setting.API.DefaultGitTreesPerPage
} else {
perPage = len(entries)
}
}
if page <= 0 {
page = 1


+ 411
- 0
modules/repofiles/update.go View File

@@ -7,6 +7,7 @@ package repofiles
import (
"bytes"
"container/list"
"encoding/base64"
"fmt"
"path"
"strings"
@@ -50,6 +51,7 @@ type UpdateRepoFileOptions struct {
Content string
SHA string
IsNewFile bool
Type string
Author *IdentityOptions
Committer *IdentityOptions
Dates *CommitDateOptions
@@ -462,6 +464,415 @@ func CreateOrUpdateRepoFile(repo *models.Repository, doer *models.User, opts *Up
return file, nil
}

func OneTimeSubmission(repo *models.Repository, doer *models.User, optsList[] *UpdateRepoFileOptions) error {
base := *optsList[0]

t, err := NewTemporaryUploadRepository(repo)
if err != nil {
log.Error("%v", err)
}
defer t.Close()
if err := t.Clone(base.OldBranch); err != nil {
return err
}
if err := t.SetDefaultIndex(); err != nil {
return err
}

// Get the commit of the original branch
commit, err := t.GetBranchCommit(base.OldBranch)
if err != nil {
return err // Couldn't get a commit for the branch
}

message := strings.TrimSpace(base.Message)
author, committer := GetAuthorAndCommitterUsers(base.Author, base.Committer, doer)


for _, opts := range optsList {
// 解码文件内容
content, err := base64.StdEncoding.DecodeString(opts.Content)
if err != nil {
return err
}
opts.Content = string(content)

// If no branch name is set, assume master
if opts.OldBranch == "" {
opts.OldBranch = repo.DefaultBranch
}
if opts.NewBranch == "" {
opts.NewBranch = opts.OldBranch
}

if _, err := repo_module.GetBranch(repo, opts.OldBranch); err != nil {
return err
}

if opts.NewBranch != opts.OldBranch {
existingBranch, err := repo_module.GetBranch(repo, opts.NewBranch)
if existingBranch != nil {
return models.ErrBranchAlreadyExists{
BranchName: opts.NewBranch,
}
}
if err != nil && !git.IsErrBranchNotExist(err) {
return err
}
} else {
protectedBranch, err := repo.GetBranchProtection(opts.OldBranch)
if err != nil {
return err
}
if protectedBranch != nil {
if !protectedBranch.CanUserPush(doer.ID) {
return models.ErrUserCannotCommit{
UserName: doer.LowerName,
}
}
if protectedBranch.RequireSignedCommits {
_, _, err := repo.SignCRUDAction(doer, repo.RepoPath(), opts.OldBranch)
if err != nil {
if !models.IsErrWontSign(err) {
return err
}
return models.ErrUserCannotCommit{
UserName: doer.LowerName,
}
}
}
patterns := protectedBranch.GetProtectedFilePatterns()
for _, pat := range patterns {
if pat.Match(strings.ToLower(opts.TreePath)) {
return models.ErrFilePathProtected{
Path: opts.TreePath,
}
}
}
}
}


// If FromTreePath is not set, set it to the opts.TreePath
if opts.TreePath != "" && opts.FromTreePath == "" {
opts.FromTreePath = opts.TreePath
}

// Check that the path given in opts.treePath is valid (not a git path)
treePath := CleanUploadFileName(opts.TreePath)
if treePath == "" {
return models.ErrFilenameInvalid{
Path: opts.TreePath,
}
}

// Assigned LastCommitID in opts if it hasn't been set
if opts.LastCommitID == "" {
opts.LastCommitID = commit.ID.String()
} else {
lastCommitID, err := t.gitRepo.ConvertToSHA1(opts.LastCommitID)
if err != nil {
return fmt.Errorf("DeleteRepoFile: Invalid last commit ID: %v", err)
}
opts.LastCommitID = lastCommitID.String()
}

// 添加修改和删除的区别
if opts.Type == "add" || opts.Type == "update"{

// If there is a fromTreePath (we are copying it), also clean it up
fromTreePath := CleanUploadFileName(opts.FromTreePath)
if fromTreePath == "" && opts.FromTreePath != "" {
return models.ErrFilenameInvalid{
Path: opts.FromTreePath,
}
}

encoding := "UTF-8"
bom := false
executable := false

if !opts.IsNewFile {
fromEntry, err := commit.GetTreeEntryByPath(fromTreePath)
if err != nil {
return err
}
if opts.SHA != "" {
// If a SHA was given and the SHA given doesn't match the SHA of the fromTreePath, throw error
if opts.SHA != fromEntry.ID.String() {
return models.ErrSHADoesNotMatch{
Path: treePath,
GivenSHA: opts.SHA,
CurrentSHA: fromEntry.ID.String(),
}
}
} else if opts.LastCommitID != "" {
// If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw
// an error, but only if we aren't creating a new branch.
if commit.ID.String() != opts.LastCommitID && opts.OldBranch == opts.NewBranch {
if changed, err := commit.FileChangedSinceCommit(treePath, opts.LastCommitID); err != nil {
return err
} else if changed {
return models.ErrCommitIDDoesNotMatch{
GivenCommitID: opts.LastCommitID,
CurrentCommitID: opts.LastCommitID,
}
}
// The file wasn't modified, so we are good to delete it
}
} else {
// When updating a file, a lastCommitID or SHA needs to be given to make sure other commits
// haven't been made. We throw an error if one wasn't provided.
return models.ErrSHAOrCommitIDNotProvided{}
}
encoding, bom = detectEncodingAndBOM(fromEntry, repo)
executable = fromEntry.IsExecutable()
}

treePathParts := strings.Split(treePath, "/")
subTreePath := ""
for index, part := range treePathParts {
subTreePath = path.Join(subTreePath, part)
entry, err := commit.GetTreeEntryByPath(subTreePath)
if err != nil {
if git.IsErrNotExist(err) {
// Means there is no item with that name, so we're good
break
}
return err
}
if index < len(treePathParts)-1 {
if !entry.IsDir() {
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a file exists where you’re trying to create a subdirectory [path: %s]", subTreePath),
Path: subTreePath,
Name: part,
Type: git.EntryModeBlob,
}
}
} else if entry.IsLink() {
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a symbolic link exists where you’re trying to create a subdirectory [path: %s]", subTreePath),
Path: subTreePath,
Name: part,
Type: git.EntryModeSymlink,
}
} else if entry.IsDir() {
return models.ErrFilePathInvalid{
Message: fmt.Sprintf("a directory exists where you’re trying to create a file [path: %s]", subTreePath),
Path: subTreePath,
Name: part,
Type: git.EntryModeTree,
}
} else if fromTreePath != treePath || opts.IsNewFile {
// The entry shouldn't exist if we are creating new file or moving to a new path
return models.ErrRepoFileAlreadyExists{
Path: treePath,
}
}

}

// Get the two paths (might be the same if not moving) from the index if they exist
filesInIndex, err := t.LsFiles(opts.TreePath, opts.FromTreePath)
if err != nil {
return fmt.Errorf("UpdateRepoFile: %v", err)
}
// If is a new file (not updating) then the given path shouldn't exist
if opts.IsNewFile {
for _, file := range filesInIndex {
if file == opts.TreePath {
return models.ErrRepoFileAlreadyExists{
Path: opts.TreePath,
}
}
}
}

// Remove the old path from the tree
if fromTreePath != treePath && len(filesInIndex) > 0 {
for _, file := range filesInIndex {
if file == fromTreePath {
if err := t.RemoveFilesFromIndex(opts.FromTreePath); err != nil {
return err
}
}
}
}

content := opts.Content
if bom {
content = string(charset.UTF8BOM) + content
}
if encoding != "UTF-8" {
charsetEncoding, _ := stdcharset.Lookup(encoding)
if charsetEncoding != nil {
result, _, err := transform.String(charsetEncoding.NewEncoder(), content)
if err != nil {
// Look if we can't encode back in to the original we should just stick with utf-8
log.Error("Error re-encoding %s (%s) as %s - will stay as UTF-8: %v", opts.TreePath, opts.FromTreePath, encoding, err)
result = content
}
content = result
} else {
log.Error("Unknown encoding: %s", encoding)
}
}
// Reset the opts.Content to our adjusted content to ensure that LFS gets the correct content
opts.Content = content
var lfsMetaObject *models.LFSMetaObject

if setting.LFS.StartServer {
// Check there is no way this can return multiple infos
filename2attribute2info, err := t.CheckAttribute("filter", treePath)
if err != nil {
return err
}

if filename2attribute2info[treePath] != nil && filename2attribute2info[treePath]["filter"] == "lfs" {
// OK so we are supposed to LFS this data!
oid, err := models.GenerateLFSOid(strings.NewReader(opts.Content))
if err != nil {
return err
}
lfsMetaObject = &models.LFSMetaObject{Oid: oid, Size: int64(len(opts.Content)), RepositoryID: repo.ID}
content = lfsMetaObject.Pointer()
}
}
// Add the object to the database
objectHash, err := t.HashObject(strings.NewReader(content))
if err != nil {
return err
}

// Add the object to the index
if executable {
if err := t.AddObjectToIndex("100755", objectHash, treePath); err != nil {
return err
}
} else {
if err := t.AddObjectToIndex("100644", objectHash, treePath); err != nil {
return err
}
}

if lfsMetaObject != nil {
// We have an LFS object - create it
lfsMetaObject, err = models.NewLFSMetaObject(lfsMetaObject)
if err != nil {
return err
}
contentStore := &lfs.ContentStore{BasePath: setting.LFS.ContentPath}
if !contentStore.Exists(lfsMetaObject) {
if err := contentStore.Put(lfsMetaObject, strings.NewReader(opts.Content)); err != nil {
if _, err2 := repo.RemoveLFSMetaObjectByOid(lfsMetaObject.Oid); err2 != nil {
return fmt.Errorf("Error whilst removing failed inserted LFS object %s: %v (Prev Error: %v)", lfsMetaObject.Oid, err2, err)
}
return err
}
}
}
} else {
// Get the files in the index
filesInIndex, err := t.LsFiles(opts.TreePath)
if err != nil {
return fmt.Errorf("DeleteRepoFile: %v", err)
}

// Find the file we want to delete in the index
inFilelist := false
for _, file := range filesInIndex {
if file == opts.TreePath {
inFilelist = true
break
}
}
if !inFilelist {
return models.ErrRepoFileDoesNotExist{
Path: opts.TreePath,
}
}

// Get the entry of treePath and check if the SHA given is the same as the file
entry, err := commit.GetTreeEntryByPath(treePath)
if err != nil {
return err
}
if opts.SHA != "" {
// If a SHA was given and the SHA given doesn't match the SHA of the fromTreePath, throw error
if opts.SHA != entry.ID.String() {
return models.ErrSHADoesNotMatch{
Path: treePath,
GivenSHA: opts.SHA,
CurrentSHA: entry.ID.String(),
}
}
} else if opts.LastCommitID != "" {
// If a lastCommitID was given and it doesn't match the commitID of the head of the branch throw
// an error, but only if we aren't creating a new branch.
if commit.ID.String() != opts.LastCommitID && opts.OldBranch == opts.NewBranch {
// CommitIDs don't match, but we don't want to throw a ErrCommitIDDoesNotMatch unless
// this specific file has been edited since opts.LastCommitID
if changed, err := commit.FileChangedSinceCommit(treePath, opts.LastCommitID); err != nil {
return err
} else if changed {
return models.ErrCommitIDDoesNotMatch{
GivenCommitID: opts.LastCommitID,
CurrentCommitID: opts.LastCommitID,
}
}
// The file wasn't modified, so we are good to delete it
}
} else {
// When deleting a file, a lastCommitID or SHA needs to be given to make sure other commits haven't been
// made. We throw an error if one wasn't provided.
return models.ErrSHAOrCommitIDNotProvided{}
}

// Remove the file from the index
if err := t.RemoveFilesFromIndex(opts.TreePath); err != nil {
return err
}
}

base = *opts
}

// Now write the tree
treeHash, err := t.WriteTree()
if err != nil {
return err
}
// Now commit the tree
var commitHash string
if base.Dates != nil {
commitHash, err = t.CommitTreeWithDate(author, committer, treeHash, message, base.Dates.Author, base.Dates.Committer)
} else {
commitHash, err = t.CommitTree(author, committer, treeHash, message)

}
if err != nil {
return err
}

// Then push this tree to NewBranch
if err := t.Push(doer, commitHash, base.NewBranch); err != nil {
log.Error("%T %v", err, err)
return err
}

commit, err = t.GetCommit(commitHash)
if err != nil {
return err
}

_, err = GetFileCommitResponse(repo, commit)
if err != nil {
return err
}
return nil
}

// PushUpdateOptions defines the push update options
type PushUpdateOptions struct {
PusherID int64


+ 61
- 8
modules/setting/setting.go View File

@@ -545,6 +545,7 @@ var (
BrainScoreOwner string
BrainScoreName string
BrainScoreServerHost string
BrainScoreRegion []string

IsSnn4EcosetEnabled bool
Snn4EcosetOwner string
@@ -552,6 +553,13 @@ var (
Snn4EcosetServerHost string
Snn4AttachmentName string

IsSim2BrainSnnEnabled bool
Sim2BrainSnnOwner string
Sim2BrainSnnName string
Sim2BrainSnnServerHost string
Sim2BrainSnnDatasetTypes []string
Sim2BrainSnnAttachNames []string

//blockchain config
BlockChainHost string
CommitValidDate string
@@ -663,6 +671,7 @@ var (
CloudBrainPayInterval time.Duration
DeductTaskRange time.Duration
DeductTaskRangeForFirst time.Duration
DeductTaskMinTimestamp int64

//badge config
BadgeIconMaxFileSize int64
@@ -679,20 +688,38 @@ var (
TreePathOfSubscribe string

//wechat template msg config
CloudbrainStartedTemplateId string
CloudbrainStartedNotifyList []string
CloudbrainStartedTitle string
CloudbrainStartedRemark string
CloudbrainStoppedTemplateId string
CloudbrainStoppedNotifyList []string
CloudbrainStoppedTitle string
CloudbrainStoppedRemark string
CloudbrainStartedTemplateId string
CloudbrainStartedNotifyList []string
CloudbrainStartedTitle string
CloudbrainStartedRemark string
CloudbrainStoppedTemplateId string
CloudbrainStoppedNotifyList []string
CloudbrainStoppedTitle string
CloudbrainStoppedRemark string
CloudbrainComingStopTemplateId string
CloudbrainComingStopTitle string
CloudbrainComingStopChargeLink string
CloudbrainComingStopRemark string
CloudbrainComingStopSendFlag bool

//repo square config
IncubationSourceOrgName string
PaperRepoTopicName string

CloudbrainUniquenessLockTime time.Duration
SyncCloudbrainStatusDuration string

//wenxin url
BaiduWenXin = struct {
ModelArtsWenXinURL string
BAIDU_API_KEY string
BAIDU_SECRET_KEY string
BAIDU_TOKEN_URL string
PICTURE_BAIDU_REVIEW_URL string
TEXT_BAIDU_REVIEW_URL string
RUN_WORKERS int
MODEL_SERVERS int
}{}

//nginx proxy
PROXYURL string
@@ -1514,6 +1541,7 @@ func NewContext() {
DebugAttachSize = sec.Key("DEBUG_ATTACH_SIZE").MustInt(20)

CloudbrainUniquenessLockTime = sec.Key("UNIQUENESS_LOCK_TIME").MustDuration(5 * time.Minute)
SyncCloudbrainStatusDuration = sec.Key("SYNC_STATUS_DURATION").MustString("@every 1m")

sec = Cfg.Section("benchmark")
IsBenchmarkEnabled = sec.Key("ENABLED").MustBool(false)
@@ -1538,6 +1566,7 @@ func NewContext() {
BrainScoreOwner = sec.Key("OWNER").MustString("")
BrainScoreName = sec.Key("NAME").MustString("")
BrainScoreServerHost = sec.Key("HOST").MustString("")
BrainScoreRegion = strings.Split(sec.Key("REGION").MustString(""), ",")

sec = Cfg.Section("snn4ecoset")
IsSnn4EcosetEnabled = sec.Key("ENABLED").MustBool(false)
@@ -1546,6 +1575,14 @@ func NewContext() {
Snn4EcosetServerHost = sec.Key("HOST").MustString("")
Snn4AttachmentName = sec.Key("DATASET").MustString("")

sec = Cfg.Section("sim2brain_snn")
IsSim2BrainSnnEnabled = sec.Key("ENABLED").MustBool(false)
Sim2BrainSnnOwner = sec.Key("OWNER").MustString("")
Sim2BrainSnnName = sec.Key("NAME").MustString("")
Sim2BrainSnnServerHost = sec.Key("HOST").MustString("")
Sim2BrainSnnDatasetTypes = strings.Split(sec.Key("DATASET_TYPE").MustString(""), ",")
Sim2BrainSnnAttachNames = strings.Split(sec.Key("ATTACH_NAME").MustString(""), ",")

sec = Cfg.Section("blockchain")
BlockChainHost = sec.Key("HOST").MustString("http://192.168.136.66:3302/")
CommitValidDate = sec.Key("COMMIT_VALID_DATE").MustString("2021-01-15")
@@ -1618,6 +1655,11 @@ func NewContext() {
CloudbrainStoppedNotifyList = strings.Split(sec.Key("CLOUDBRAIN_STOPPED_NOTIFY_LIST").MustString("TRAIN"), ",")
CloudbrainStoppedTitle = sec.Key("CLOUDBRAIN_STOPPED_TITLE").MustString("您好,您申请的算力资源已结束使用,任务已完成运行,状态为%s,请您关注运行结果")
CloudbrainStoppedRemark = sec.Key("CLOUDBRAIN_STOPPED_REMARK").MustString("感谢您的耐心等待。")
CloudbrainComingStopTemplateId = sec.Key("CLOUDBRAIN_COMING_STOP_TEMPLATE_ID").MustString("")
CloudbrainComingStopTitle = sec.Key("CLOUDBRAIN_COMING_STOP_TITLE").MustString("因算力积分余额不足,您正在运行的任务即将被停止。")
CloudbrainComingStopChargeLink = sec.Key("CLOUDBRAIN_COMING_STOP_CHARGE_LINK").MustString("请参考“个人中心 > 算力积分”页面的“积分获取说明”获取积分。")
CloudbrainComingStopRemark = sec.Key("CLOUDBRAIN_COMING_STOP_REMARK").MustString("为了不影响您使用,请您尽快获取算力积分。")
CloudbrainComingStopSendFlag = sec.Key("CLOUDBRAIN_COMING_STOP_SEND_FLAG").MustBool(true)

sec = Cfg.Section("repo-square")
IncubationSourceOrgName = sec.Key("INCUBATION_ORG_NAME").MustString("OpenI")
@@ -1629,6 +1671,7 @@ func NewContext() {
CloudBrainPayInterval = sec.Key("CLOUDBRAIN_PAY_INTERVAL").MustDuration(60 * time.Minute)
DeductTaskRange = sec.Key("DEDUCT_TASK_RANGE").MustDuration(30 * time.Minute)
DeductTaskRangeForFirst = sec.Key("DEDUCT_TASK_RANGE_FOR_FIRST").MustDuration(3 * time.Hour)
DeductTaskMinTimestamp = sec.Key("DEDUCT_TASK_MIN_TIMESTAMP").MustInt64(0)

sec = Cfg.Section("icons")
BadgeIconMaxFileSize = sec.Key("BADGE_ICON_MAX_FILE_SIZE").MustInt64(1048576)
@@ -1663,6 +1706,16 @@ func NewContext() {
sec = Cfg.Section("kanban")
IsCloudbrainTimingEnabled = sec.Key("ENABLED").MustBool(false)

sec = Cfg.Section("wenxin")
BaiduWenXin.ModelArtsWenXinURL = sec.Key("ModelArts_WenXinURL").MustString("")
BaiduWenXin.BAIDU_API_KEY = sec.Key("BAIDU_API_KEY").MustString("")
BaiduWenXin.BAIDU_SECRET_KEY = sec.Key("BAUDY_SECRET_KEY").MustString("")
BaiduWenXin.BAIDU_TOKEN_URL = sec.Key("BAIDU_TOKEN_URL").MustString("https://aip.baidubce.com/oauth/2.0/token")
BaiduWenXin.PICTURE_BAIDU_REVIEW_URL = sec.Key("PICTURE_BAIDU_REVIEW_URL").MustString("https://aip.baidubce.com/rest/2.0/solution/v1/img_censor/v2/user_defined?access_token=")
BaiduWenXin.TEXT_BAIDU_REVIEW_URL = sec.Key("TEXT_BAIDU_REVIEW_URL").MustString("https://aip.baidubce.com/rest/2.0/solution/v1/text_censor/v2/user_defined?access_token=")
BaiduWenXin.RUN_WORKERS = sec.Key("RUN_WORKERS").MustInt(1)
BaiduWenXin.MODEL_SERVERS = sec.Key("MODEL_SERVERS").MustInt(1)

getGrampusConfig()
getModelartsCDConfig()
getModelConvertConfig()


+ 1
- 5
modules/storage/storage.go View File

@@ -74,13 +74,9 @@ func Init() error {
ObsCli, err = obs.New(setting.AccessKeyID, setting.SecretAccessKey, setting.Endpoint)
if err != nil {
log.Error("obs.New failed:", err)
return err
//return err
}
log.Info("obs cli inited.")

if err != nil {
return err
}

return nil
}

+ 17
- 0
modules/structs/cloudbrain.go View File

@@ -40,9 +40,26 @@ type CreateTrainJobOption struct {
PreTrainModelUrl string `json:"pre_train_model_url"`
SpecId int64 `json:"spec_id" binding:"Required"`
}
type CreateNotebookOption struct {
Type int `json:"type"`
DisplayJobName string `json:"display_job_name" binding:"Required"`
Attachment string `json:"attachment"`
ImageID string `json:"image_id"`
Description string `json:"description"`
BranchName string `json:"branch_name" binding:"Required"`
Image string `json:"image" binding:"Required"`
DatasetName string `json:"dataset_name"`
ModelName string `json:"model_name"`
ModelVersion string `json:"model_version"`
CkptName string `json:"ckpt_name"`
LabelName string `json:"label_names"`
PreTrainModelUrl string `json:"pre_train_model_url"`
SpecId int64 `json:"spec_id" binding:"Required"`
}

type CreateFileNotebookJobOption struct {
Type int `json:"type"` //0 CPU 1 GPU 2 NPU
Image string `json:"image"`
File string `json:"file" binding:"Required"`
BranchName string `json:"branch_name" binding:"Required"`
OwnerName string `json:"owner_name" binding:"Required"`


+ 28
- 0
modules/structs/repo_file.go View File

@@ -48,6 +48,32 @@ type UpdateFileOptions struct {
FromPath string `json:"from_path" binding:"MaxSize(500)"`
}

// CommitMultiFileOptions options for commit multi files
type CommitMultiFileOptions struct {
Files []CommitFileOptions `json:"files"`
Msg string `json:"msg"`
CurrentBranch string `json:"currentBranch"`
CommitBranch string `json:"commitBranch"`
}

// CommitFileOptions options for commit files
// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
type CommitFileOptions struct {
FileOptions
// file path
FilePath string `json:"filePath"`
// content must be base64 encoded
Content string `json:"content"`
// sha is the SHA for the file that already exists
SHA string `json:"sha"`

// from_path (optional) is the path of the original file which will be moved/renamed to the path in the URL
FromPath string `json:"from_path" binding:"MaxSize(500)"`
// operation: add, update, delete
// required: true
Operation string `json:"operation"`
}

// FileLinksResponse contains the links for a repo's file
type FileLinksResponse struct {
Self *string `json:"self"`
@@ -76,6 +102,8 @@ type ContentsResponse struct {
// `submodule_git_url` is populated when `type` is `submodule`, otherwise null
SubmoduleGitURL *string `json:"submodule_git_url"`
Links *FileLinksResponse `json:"_links"`
Language string `json:"language"`
FileType string `json:"fileType"`
}

// FileCommitResponse contains information generated from a Git commit for a repo's file.


+ 18
- 0
modules/structs/repo_tree.go View File

@@ -14,6 +14,14 @@ type GitEntry struct {
URL string `json:"url"`
}

// GitEntryWithChildren represents a git tree entry with children
type GitEntryWithChildren struct {
GitEntry
Children []GitEntryWithChildren `json:"children"`
Name string `json:"name"`
Suffix string `json:"suffix"`
}

// GitTreeResponse returns a git tree
type GitTreeResponse struct {
SHA string `json:"sha"`
@@ -23,3 +31,13 @@ type GitTreeResponse struct {
Page int `json:"page"`
TotalCount int `json:"total_count"`
}

// GitTreeWithChildrenResponse returns a git tree with children
type GitTreeWithChildrenResponse struct {
SHA string `json:"sha"`
URL string `json:"url"`
Entries []GitEntryWithChildren `json:"tree"`
Truncated bool `json:"truncated"`
Page int `json:"page"`
TotalCount int `json:"total_count"`
}

+ 18
- 0
modules/structs/tech.go View File

@@ -0,0 +1,18 @@
package structs

type NotOpenITechRepo struct {
Url string `json:"url" binding:"Required"`
TechNo string `json:"no"`
Institution string `json:"institution"`
UID int64 `json:"uid"` //启智项目uid
RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
Alias string `json:"alias" binding:"Required;AlphaDashDotChinese;MaxSize(100)"`
Topics []string `json:"topics"` //关键词
Description string `json:"description" binding:"MaxSize(255)"`
}

type OpenITechRepo struct {
Url string `json:"url" binding:"Required"`
TechNo string `json:"no"`
Institution string `json:"institution"`
}

+ 2
- 1
modules/templates/helper.go View File

@@ -374,7 +374,7 @@ func NewTextFuncMap() []texttmpl.FuncMap {
"AppDomain": func() string {
return setting.Domain
},
"TimeStampNow": timeutil.TimeStampNow,
"TimeStampNow": timeutil.TimeStampNow,
"TimeSince": timeutil.TimeSince,
"TimeSinceUnix": timeutil.TimeSinceUnix,
"TimeSinceUnix1": timeutil.TimeSinceUnix1,
@@ -485,6 +485,7 @@ func subOne(length int) int {
func addOne(length int64) int64 {
return length + 1
}

// Escape escapes a HTML string
func Escape(raw string) string {
return html.EscapeString(raw)


+ 22
- 0
options/locale/locale_en-US.ini View File

@@ -3313,6 +3313,7 @@ SNN4IMAGENET = BENCHMARK
BRAINSCORE = BENCHMARK
SNN4ECOSET = BENCHMARK
MODELSAFETY = BENCHMARK
SIM2BRAIN_SNN = BENCHMARK
TRAIN = TRAIN
INFERENCE = INFERENCE
BENCHMARK = BENCHMARK
@@ -3324,6 +3325,7 @@ Already_stopped=The job is already stopped.
Stopped_failed=Fail to stop the job, please try again later.
Stopped_success_update_status_fail=Succeed in stopping th job, but failed to update the job status and duration time.
load_code_failed=Fail to load code, please check if the right branch is selected.
dataset_load_fail=Fail to load dataset.

error.debug_datasetsize = The size of dataset exceeds limitation (%dGB)
error.dataset_select = dataset select error:the count exceed the limit or has same name
@@ -3357,7 +3359,27 @@ targetted = targetted
new_model_security_evaluation_tips = Model Security Evaluation just used for image classification

[model_app]
get_file_fail = Can not get the image content, please try again later.
content_type_unsupported = Allowed image type is jpg, jpeg or png.
process_image_fail = Fail to process image, please try again later.
model_case = Model Case
wenxin_paint_model = ERNIE-ViLGAI painting large model
wenxin_paint_model_desc = The world largest Chinese cross-modal generation model can realize image generation and editing through natural language
desensitize_model = Data desensitization model experience
desensitize_model_desc = Use AI technology to desensitize the face and license plate number in the picture
more_model_case = More experiences are continuously updated...
get_file_fail= Can not get the image content, please try again later.
content_type_unsupported=Allowed image type is jpg, jpeg or png.
process_image_fail=Fail to process image, please try again later.

[tech]
get_file_fail= Can not get the file content, please try again later.
content_type_unsupported=The format of the file or file content is wrong.
sql_err=Fail to process data, please try again later.
show_or_hide_fail=Failed to %s the repo(s).
incorrect_openi_format = The OpenI address format is incorrect
openi_repo_not_exist = OpenI repository is not exists
tech_not_exist = The project approval number does not exist
institution_not_valid = The submitted contributing unit is not among the participating units of the technology project
repo_converge_exists = The technology project [%s] already has [%s], please do not submit it again
to_migrate_repo_exists = The project has been migrated to OpenI, please use the OpenI way to submit

+ 24
- 0
options/locale/locale_zh-CN.ini View File

@@ -3334,6 +3334,7 @@ SNN4IMAGENET = 评测任务
BRAINSCORE = 评测任务
SNN4ECOSET = 评测任务
MODELSAFETY = 评测任务
SIM2BRAIN_SNN = 评测任务
TRAIN = 训练任务
INFERENCE = 推理任务
BENCHMARK = 评测任务
@@ -3345,6 +3346,7 @@ Already_stopped=任务已停止。
Stopped_failed=任务停止失败,请稍后再试。
Stopped_success_update_status_fail=任务停止成功,状态及运行时间更新失败。
load_code_failed=代码加载失败,请确认选择了正确的分支。
dataset_load_fail=数据集加载失败。

error.debug_datasetsize = 数据集大小超过限制(%dGB)
error.dataset_select = 数据集选择错误:数量超过限制或者有同名数据集
@@ -3378,7 +3380,29 @@ targetted = 定向
new_model_security_evaluation_tips = 模型安全评测只适用于图像分类

[model_app]
get_file_fail = 获取上传文件失败,请稍后再试。
content_type_unsupported = 请上传jpg、jpeg或png图片。
process_image_fail = 图片处理失败,请稍后再试。
model_case = 模型体验
wenxin_paint_model = ERNIE-ViLGAI 作画大模型
wenxin_paint_model_desc = 全球规模最大的中文跨模态生成模型,可通过自然语言实现图像生成与编辑
desensitize_model = 数据脱敏模型体验
desensitize_model_desc = 利用人工智能AI技术,把图片中的人脸、车牌号码进行脱敏处理
more_model_case = 更多体验持续更新中…
get_file_fail= 获取上传文件失败,请稍后再试。
content_type_unsupported=请上传jpg、jpeg或png图片。
process_image_fail=图片处理失败,请稍后再试。
[tech]
get_file_fail= 获取上传文件失败。
content_type_unsupported=上传文件的格式有误。
sql_err=数据处理错误,请稍后再试。
show_or_hide_fail=%s失败。
incorrect_openi_format = 启智项目地址格式错误
openi_repo_not_exist = 启智项目不存在
tech_not_exist = 项目立项编号不存在
institution_not_valid = 当前提交的贡献单位不在该科技项目的参与单位中
repo_converge_exists = 科技项目[%s]中已存在[%s],请勿重复提交
to_migrate_repo_exists = 该项目已迁移到启智,请使用 方式提交申请




+ 22281
- 172
package-lock.json
File diff suppressed because it is too large
View File


+ 7
- 1
package.json View File

@@ -52,6 +52,7 @@
"svgo-loader": "2.2.1",
"swagger-ui": "3.25.3",
"terser-webpack-plugin": "3.0.1",
"uuidv1": "1.6.14",
"vue": "2.6.11",
"vue-bar-graph": "1.2.0",
"vue-calendar-heatmap": "0.8.4",
@@ -59,8 +60,10 @@
"vue-loader": "15.9.2",
"vue-router": "3.3.4",
"vue-template-compiler": "2.6.11",
"vue-tree-list": "1.5.0",
"webpack": "4.43.0",
"webpack-cli": "3.3.11",
"webpack-cli": "3.3.12",
"webpack-dev-server": "4.9.3",
"webpack-fix-style-only-entries": "0.4.0",
"worker-loader": "2.0.0",
"xlsx": "0.17.3"
@@ -78,6 +81,9 @@
"typescript": "4.5.5",
"updates": "10.2.11"
},
"scripts": {
"start": "make watch-frontend && ./opendata"
},
"browserslist": [
"defaults"
]


BIN
public/0acc017d3b9b32f1f61a9af2315d5187.png View File

Before After
Width: 44  |  Height: 48  |  Size: 994 B

BIN
public/0f1600ced2415ea9530a1a55ec045fef.png View File

Before After
Width: 28  |  Height: 28  |  Size: 801 B

BIN
public/1f2e7b26b1be5e67e613178f38625008.png View File

Before After
Width: 44  |  Height: 48  |  Size: 1.0 KiB

BIN
public/276e9642cca7e5f8958c004269a6c0d7.png View File

Before After
Width: 360  |  Height: 313  |  Size: 24 KiB

BIN
public/41fa1ffe704082c381ae88ea686c9f39.png View File

Before After
Width: 44  |  Height: 20  |  Size: 567 B

BIN
public/5920c99e273bded4a2c702d4a1ed59ee.png View File

Before After
Width: 28  |  Height: 32  |  Size: 608 B

BIN
public/6f562e238482d4479212cbf367f6a293.png View File

Before After
Width: 28  |  Height: 32  |  Size: 542 B

BIN
public/71261d74041a4133ae4b9908d4a8109f.png View File

Before After
Width: 48  |  Height: 48  |  Size: 1.1 KiB

BIN
public/d4f9fbedc79f92e41f984283b6227127.png View File

Before After
Width: 48  |  Height: 48  |  Size: 1.2 KiB

+ 93
- 21
public/home/home.js View File

@@ -812,6 +812,73 @@ function getRecommendModule() {
function initHomeTopBanner() {
var homeSlideTimer = null;
var homeSlideDuration = 8000;

function getBannerData() {
$.ajax({
type: "GET",
url: "/dashboard/invitation",
headers: { authorization: token, },
dataType: "json",
data: { filename: 'home/banner', },
success: function (data) {
try {
var banners = JSON.parse(data);
var count = 0, bannerList = [];
for (var i = 0; i < banners.length; i++) {
(function (banner, index) {
$.ajax({
type: "GET",
url: "/dashboard/invitation",
headers: { authorization: token, },
data: { filename: 'home/banners/' + banner },
success: function (data) {
count++;
bannerList[index] = {
banner: banner,
data: data,
};
if (count == banners.length) {
renderBanners(bannerList);
}
},
error: function (err) {
count++;
if (count == data.length) {
startSlide();
}
console.log(err);
}
});
})(banners[i], i);
}
if (!banners.length) {
startSlide();
}
} catch (err) {
console.log(err);
startSlide();
}
},
error: function (err) {
console.log(err);
startSlide();
}
});
}

function renderBanners(bannerList) {
var hmPageC = $('._hm-bg-container ._hm-pg-c');
var hmPageSlidePaginationC = $('._hm-slide-pagination-c');
for (var i = 0, iLen = bannerList.length; i < iLen; i++) {
var banner = bannerList[i];
if (banner.data) {
hmPageC.append($(banner.data));
hmPageSlidePaginationC.append('<div class="_hm-slide-pagination-item"></div>');
}
}
startSlide();
}

function homeSlide(direction, index) {
var slidePages = $('._hm-pg-c ._hm-pg');
var currentPage = slidePages.filter('._hm-pg-show');
@@ -832,8 +899,9 @@ function initHomeTopBanner() {
}

function startSlide() {
$('._hm-slide-pagination-c').show();
homeSlideTimer && clearTimeout(homeSlideTimer);
homeSlideTimer = setTimeout(function() {
homeSlideTimer = setTimeout(function () {
homeSlide('right');
startSlide();
}, homeSlideDuration);
@@ -843,26 +911,30 @@ function initHomeTopBanner() {
homeSlideTimer && clearTimeout(homeSlideTimer);
}

$('._hm-slide-btn').on('click', function () {
if ($(this).hasClass('_hm-slide-btn-left')) {
homeSlide('left');
} else {
homeSlide('right');
}
startSlide();
});
$('._hm-pg #homenews').on('mouseenter', function() {
stopSlide();
}).on('mouseleave', function() {
startSlide();
});
$('._hm-slide-pagination-c ._hm-slide-pagination-item').on('click', function() {
var self = $(this);
if (self.hasClass('_hm-slide-pagination-item-active')) return;
homeSlide('', self.index());
startSlide();
});
setTimeout(function() { startSlide(); }, 500);
function eventInit() {
$('._hm-slide-btn').on('click', function () {
if ($(this).hasClass('_hm-slide-btn-left')) {
homeSlide('left');
} else {
homeSlide('right');
}
startSlide();
});
$('._hm-pg #homenews').on('mouseenter', function () {
stopSlide();
}).on('mouseleave', function () {
startSlide();
});
$('._hm-slide-pagination-c').on('click', '._hm-slide-pagination-item', function () {
var self = $(this);
if (self.hasClass('_hm-slide-pagination-item-active')) return;
homeSlide('', self.index());
startSlide();
});
}

getBannerData();
eventInit();
}

initHomeTopBanner();


+ 21
- 0
public/html/js/nbview/LICENSE.txt View File

@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2015, Jeremy Singer-Vine

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

+ 22
- 0
public/html/js/nbview/Makefile View File

@@ -0,0 +1,22 @@
default:

cdnjs=https://cdnjs.cloudflare.com/ajax/libs/

.PHONY: js/vendor css/vendor
js/vendor:
curl -s $(cdnjs)es5-shim/4.5.14/es5-shim.min.js > $@/es5-shim.min.js
curl -s $(cdnjs)marked/4.1.1/marked.min.js > $@/marked.min.js
curl -s $(cdnjs)dompurify/2.4.0/purify.min.js > $@/purify.min.js
curl -s $(cdnjs)KaTeX/0.12.0/katex.min.js > $@/katex.min.js
curl -s $(cdnjs)KaTeX/0.12.0/contrib/auto-render.min.js > $@/katex-auto-render.min.js
@echo "💫 Manually download prism.min.js from 'https://prismjs.com/download.html#themes=prism&languages=markup+clike+javascript+julia+python+r'"

css/vendor:
curl -s $(cdnjs)KaTeX/0.12.0/katex.min.css > $@/katex.min.css
curl -sL https://github.com/KaTeX/katex-fonts/archive/master.zip > katex-fonts.zip
rm -rf $@/fonts
unzip -j katex-fonts.zip "katex-fonts-master/fonts/*" -d $@/fonts
rm -f katex-fonts.zip
@echo "💫 Manually download prism.css from 'https://prismjs.com/download.html#themes=prism&languages=markup+clike+javascript+julia+python+r'"

vendor: js/vendor css/vendor

+ 25
- 0
public/html/js/nbview/README.md View File

@@ -0,0 +1,25 @@
# nbpreview

`nbpreview` is a [Jupyter](http://jupyter.org/)/[IPython](http://ipython.org/) notebook previewer. It does not require an internet connection, or even having Jupyter/IPython installed.

You can use [__this hosted version__](https://jsvine.github.io/nbpreview/) or `git clone` your own. Just drag-and-drop your `.ipynb` file onto the filepicker, and *voilà!*

## Local / Offline Usage

To run `nbpreview` on your own computer, clone or [download](archive/master.zip) this repository, and then open `index.html`.

Alternatively, you can run a local server by executing `python3 -m http.server 8000` in the `nbpreview` directory, after which you can visit [http://localhost:8000](http://localhost:8000).

## Built on ...

- [notebookjs](https://github.com/jsvine/notebookjs), for notebook-rendering
- [dompurify](https://github.com/cure53/DOMPurify), for HTML sanitization
- [prism](http://prismjs.com/), for code-highlighting
- [marked](https://github.com/chjj/marked), for markdown-rendering
- [ansi_up](https://github.com/drudru/ansi_up), for ANSI-rendering
- [katex](https://github.com/KaTeX/KaTeX), for math typesetting
- [es5-shim](https://github.com/es-shims/es5-shim), for JavaScript compatibility

## Contributing

Contributions are welcome. If you'd like to suggest a new feature, please open an issue to discuss the proposal before submitting a pull request.

+ 35
- 0
public/html/js/nbview/css/nbpreview.css View File

@@ -0,0 +1,35 @@
body {
font-family: Helvetica Neue, Helvetica, sans-serif;
font-size: 14px;
}

#main {
width: 99%;
max-width: 750px;
margin: 0 auto;
}

#header {
line-height: 2;
margin-bottom: 0.25em;
font-weight: bold;
}

#controls {
border: 1px dotted #CCC;
padding: 0.75em;
margin-bottom: 0.5em;
background-color: #EEF;
}

#footer {
border: 1px dotted #CCC;
background-color: #EEF;
font-size: 0.8em;
padding: 0.5em;
text-align: center;
}

#footer a, #footer a:visited {
color: #0077EE;
}

+ 85
- 0
public/html/js/nbview/css/notebook.css View File

@@ -0,0 +1,85 @@
.nb-notebook {
line-height: 1.5;
}

.nb-stdout, .nb-stderr {
white-space: pre-wrap;
margin: 1em 0;
padding: 0.1em 0.5em;
}

.nb-stderr {
background-color: #FAA;
}

.nb-cell + .nb-cell {
margin-top: 0.5em;
}

.nb-output table {
border: 1px solid #000;
border-collapse: collapse;
}

.nb-output th {
font-weight: bold;
}

.nb-output th, .nb-output td {
border: 1px solid #000;
padding: 0.25em;
text-align: left;
vertical-align: middle;
border-collapse: collapse;
}

.nb-notebook blockquote {
border-left: 5px solid #CCC;
margin-left: 0;
padding-left: 1em;
}

.nb-cell {
position: relative;
}

.nb-raw-cell {
white-space: pre-wrap;
background-color: #f5f2f0;
font-family: Consolas, Monaco, 'Andale Mono', monospace;
padding: 1em;
margin: .5em 0;
}

.nb-output {
min-height: 1em;
width: 100%;
overflow-x: scroll;
border-right: 1px dotted #CCC;
}

.nb-output img {
max-width: 100%;
}

.nb-output:before, .nb-input:before {
position: absolute;
font-family: monospace;
color: #999;
left: -7.5em;
width: 7em;
text-align: right;
}

.nb-input:before {
content: "In [" attr(data-prompt-number) "]:";
}
.nb-output:before {
content: "Out [" attr(data-prompt-number) "]:";
}

// Fix pandas dataframe formatting
div[style="max-height:1000px;max-width:1500px;overflow:auto;"] {
max-height: none !important;
}


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_AMS-Regular.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_AMS-Regular.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_AMS-Regular.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Bold.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Bold.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Bold.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Regular.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Regular.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Caligraphic-Regular.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Bold.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Bold.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Bold.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Regular.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Regular.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Fraktur-Regular.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Bold.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Bold.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Bold.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-BoldItalic.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-BoldItalic.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-BoldItalic.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Italic.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Italic.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Italic.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Regular.ttf View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Regular.woff View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Main-Regular.woff2 View File


BIN
public/html/js/nbview/css/vendor/fonts/KaTeX_Math-BoldItalic.ttf View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save
Baidu
map