Compare commits

...

492 Commits

Author SHA1 Message Date
xiaoxiaoqiong 97d0d09497 Merge branch 'trustie_server' into standalone 2022-01-08 12:27:25 +08:00
yystopf f168fe3d03 Merge branch 'pre_trustie_server' into trustie_server 2022-01-07 18:05:12 +08:00
yystopf 05f5982a53 Merge branch 'standalone_develop' into pre_trustie_server 2022-01-07 18:04:55 +08:00
yystopf f76dad680a Merge pull request '上传头像、组织团队限制、文件下载问题修复、branch简化数据、webhook问题修复' (#298) from develop into standalone_develop 2022-01-07 18:03:57 +08:00
yystopf 2a09ced1ce fix: branches use branch name api 2022-01-07 15:41:50 +08:00
yystopf 7a1e6cfbad fix: issue edit and new branches only load name api 2022-01-07 15:19:10 +08:00
yystopf 47d1f727ce fix: create team count limit 2022-01-06 17:38:44 +08:00
yystopf a7665df0ea fix: download file url use cgi escape 2022-01-06 15:04:59 +08:00
yystopf 84f12adce8 fix: webhook tasks list error delay 2022-01-06 14:29:31 +08:00
yystopf 7fde1e0e12 fix: webhook field changed 2022-01-06 11:10:49 +08:00
yystopf 499734ebf9 fix: upload user image allow base64 2022-01-04 22:44:39 +08:00
yystopf f339df699e add: user upload image 2022-01-03 22:32:09 +08:00
yystopf cfd94cb3b7 fix: migrate repo username nil is excepted 2022-01-03 20:33:11 +08:00
yystopf 43e0617429 fix: webhook field changed 2021-12-30 09:47:12 +08:00
xiaoxiaoqiong 25e4a817f6 Merge branch 'pre_trustie_server' into trustie_server 2021-12-29 15:01:59 +08:00
xiaoxiaoqiong 2021cbbd5b Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-12-29 15:01:48 +08:00
xiaoxiaoqiong 5a43239ad9 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-29 15:01:25 +08:00
xiaoxiaoqiong 650dbea38b 停止trustie同步cookie 2021-12-29 15:00:37 +08:00
xiaoxiaoqiong abde13f061 Merge remote-tracking branch 'origin/standalone_develop' into standalone_develop 2021-12-29 14:23:56 +08:00
xiaoxiaoqiong 0619c5a4d9 开启dubug 2021-12-29 14:23:51 +08:00
yystopf e26871728f Merge branch 'pre_trustie_server' into trustie_server 2021-12-29 10:05:59 +08:00
yystopf ec444f3855 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-29 10:05:42 +08:00
yystopf 7beed940e9 Merge branch 'develop' into standalone_develop 2021-12-29 10:05:29 +08:00
yystopf d6b66d5324 fix 2021-12-29 09:56:49 +08:00
yystopf 0c1df3b2cb fix 2021-12-29 09:53:14 +08:00
yystopf fa86d3ea10 fix: branch delay 2021-12-29 09:50:57 +08:00
yystopf 8c99b754fb fix: create pr branch name escape 2021-12-28 18:37:44 +08:00
yystopf f3cf2c87c9 fix: create pr branch name escape 2021-12-28 18:29:58 +08:00
xiaoxiaoqiong ef55e44063 Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-12-28 16:24:56 +08:00
xxq250 a9df1ca75f Merge pull request '1224里程碑、1231里程碑内容同步至生产环境' (#297) from pre_trustie_server into trustie_server 2021-12-28 16:23:58 +08:00
yystopf 4f63caa86c Merge branch 'standalone_develop' into pre_trustie_server 2021-12-28 16:10:44 +08:00
yystopf 96b0f2d167 Merge branch 'develop' into standalone_develop 2021-12-28 16:10:16 +08:00
yystopf 8e4e6fc0ac Merge pull request '1224里程碑、1231里程碑内容' (#296) from yystopf/forgeplus:develop into develop 2021-12-28 16:09:45 +08:00
yystopf 75f3166ffa fix 2021-12-28 14:45:12 +08:00
yystopf 04bf423fcb fix 2021-12-28 14:42:55 +08:00
yystopf 51e8c9d908 fix: compare use url escape 2021-12-28 14:22:06 +08:00
yystopf 4304a35b80 fix 2021-12-28 11:07:40 +08:00
yystopf 076375633a fix 2021-12-27 17:55:02 +08:00
yystopf dbf5e711a5 fix 2021-12-27 17:44:08 +08:00
yystopf 4432e65683 fix: operate issue permission reset 2021-12-27 17:32:35 +08:00
yystopf dcf44a78f0 fix: unvalid branch name return error 2021-12-27 16:34:54 +08:00
yystopf 12edc620df fix: complete profile condition 2021-12-24 16:15:59 +08:00
yystopf 4ce03145df fix 2021-12-23 14:33:31 +08:00
yystopf 3e04a37ece add: team remove and joined template message 2021-12-23 14:26:40 +08:00
yystopf 78f464ccba fix: escape 2021-12-23 10:37:57 +08:00
yystopf 64423f1999 fix 2021-12-22 18:16:39 +08:00
yystopf 05c3f60dab fix 2021-12-22 18:08:10 +08:00
yystopf 0083ef33cb fix 2021-12-22 16:03:23 +08:00
yystopf 36b68df273 fix: remote register validate 2021-12-22 14:39:47 +08:00
yystopf e1a5918c22 add: project trends project info 2021-12-22 13:57:02 +08:00
xiaoxiaoqiong e9835796f6 Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-12-22 11:42:28 +08:00
yystopf 26ae9b35df fix: change member role and change team user team 2021-12-22 11:32:40 +08:00
yystopf 8e79b43aaf add: member bind team user 2021-12-22 11:16:27 +08:00
yystopf 056c145ff8 Merge branch 'pre_trustie_server' into trustie_server 2021-12-21 15:18:12 +08:00
yystopf c105785105 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-21 15:17:44 +08:00
yystopf c2bd78d70d Merge branch 'develop' into standalone_develop 2021-12-21 15:17:08 +08:00
yystopf d28eba6423 fix: create org error 2021-12-21 15:16:38 +08:00
yystopf 688be1bb7d fix: return issue version id 2021-12-21 15:16:38 +08:00
yystopf df69dee282 fix: some error for read raw data 2021-12-21 15:14:10 +08:00
yystopf ee6404a3b3 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-21 14:31:34 +08:00
yystopf fae8313df6 Merge branch 'develop' into standalone_develop 2021-12-21 14:31:24 +08:00
yystopf 45a77e5c07 fix: readme private file path use authorize 2021-12-21 14:24:27 +08:00
yystopf 7849bd0ebf fix: remove pr permission 2021-12-21 10:16:29 +08:00
yystopf 7f58b870d4 Merge branch 'pre_trustie_server' into trustie_server 2021-12-20 15:54:14 +08:00
yystopf 0c7499842f Merge branch 'standalone_develop' into pre_trustie_server 2021-12-20 15:53:54 +08:00
yystopf ab361d8009 Merge branch 'develop' into standalone_develop 2021-12-20 15:53:40 +08:00
yystopf 3649bf1fd0 fix 2021-12-20 15:53:24 +08:00
yystopf bcfb544cca Merge branch 'pre_trustie_server' into trustie_server 2021-12-20 15:42:54 +08:00
yystopf edb1114d39 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-20 15:42:36 +08:00
yystopf a24d33d2ee Merge pull request '同步到测试环境' (#294) from develop into standalone_develop 2021-12-20 15:42:34 +08:00
yystopf 6ffc2938a1 fix: download file url escape 2021-12-20 15:39:33 +08:00
yystopf aa60de1dac fix: valid pr title length 2021-12-20 15:38:08 +08:00
yystopf 29f98513e2 fix: org update error 2021-12-20 15:38:08 +08:00
yystopf e35cdf39fb fix: login password validate 2021-12-20 15:34:55 +08:00
yystopf 3f98e78942 Merge branch 'pre_trustie_server' into trustie_server 2021-12-17 16:25:22 +08:00
yystopf bec98bbc9d Merge branch 'standalone_develop' into pre_trustie_server 2021-12-17 15:45:57 +08:00
yystopf af160084c4 fix: merge from develop 2021-12-17 15:45:28 +08:00
yystopf e51b86538b Merge pull request '更改易修为疑修' (#292) from yystopf/forgeplus:develop into develop 2021-12-17 15:44:20 +08:00
yystopf da4fd3a762 fix: 易修 to 疑修 2021-12-17 15:35:30 +08:00
xiaoxiaoqiong 9c1ed28627 Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-12-16 10:56:30 +08:00
yystopf 01e7d857c8 Merge pull request '同步到生产环境' (#291) from pre_trustie_server into trustie_server 2021-12-16 10:52:59 +08:00
xiaoxiaoqiong 06635e8bb6 Merge branch 'pre_trustie_server' into trustie_server 2021-12-16 10:35:14 +08:00
yystopf 96d1a7440d Merge branch 'standalone_develop' into pre_trustie_server 2021-12-14 10:20:54 +08:00
yystopf 8a34699acd fix: merge from develop 2021-12-14 10:20:35 +08:00
xiaoxiaoqiong efc82b9841 fix: issue is collaborators 2021-12-14 10:17:15 +08:00
yystopf e3df503dd2 fix 2021-12-14 10:13:28 +08:00
yystopf 6a2ad67386 fix 2021-12-14 09:53:54 +08:00
yystopf 3d12db3a07 fix: atme service use perform later 2021-12-14 09:39:26 +08:00
yystopf 9c5ff55b70 Merge branch 'pre_trustie_server' into trustie_server 2021-12-13 18:35:53 +08:00
yystopf 82bae9159b Merge branch 'standalone_develop' into pre_trustie_server 2021-12-13 16:40:14 +08:00
yystopf 1d13b3686b Merge branch 'develop' into standalone_develop 2021-12-13 16:39:47 +08:00
yystopf 1faaf1d7d1 fix: project menu list wiki location 2021-12-13 11:45:58 +08:00
yystopf f8a6f62342 fix: project rank include educoder 2021-12-10 09:35:03 +08:00
yystopf b816b6a449 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-10 09:20:04 +08:00
yystopf d48700d200 Merge pull request '同步代码' (#288) from develop into standalone_develop 2021-12-10 09:19:42 +08:00
yystopf 66d1246a6c fix: educoder project menu return 2021-12-09 15:54:21 +08:00
yystopf f79beef3f9 fix: issues branch educoder use master 2021-12-09 14:33:46 +08:00
young 1aaef7315b Readme相关内容更新 2021-12-09 13:39:51 +08:00
young e64dba2166 Update README.md 2021-12-09 13:34:33 +08:00
young e0941cb3ff Update README.md 2021-12-09 13:33:26 +08:00
young 6d84867e8a Update README.md 2021-12-09 13:32:26 +08:00
young 3af96e25c2 Update README.md 2021-12-09 13:31:27 +08:00
young bb017fee1d Update README.md 2021-12-09 13:22:28 +08:00
young 33158de968 Update README.md 2021-12-09 13:21:00 +08:00
young 0ea82fb6c7 Update README.md 2021-12-09 13:19:50 +08:00
young 78499d59e4 Update README.md 2021-12-09 13:18:45 +08:00
young b530683794 Update README.md 2021-12-09 13:16:34 +08:00
young e1753be346 Update README.md 2021-12-09 13:15:34 +08:00
young 9c9b71ba82 Update README.md 2021-12-09 13:13:05 +08:00
young 8542f585a1 Update README.md 2021-12-09 13:09:12 +08:00
young cae6d3c8dd Update README.md 2021-12-09 13:07:33 +08:00
young 9f262ed66c Update README.md 2021-12-09 13:04:14 +08:00
young 2aa908ee52 Update README.md 2021-12-09 13:03:29 +08:00
young cc837516a8 Update README.md 2021-12-09 13:00:40 +08:00
young c32e1ac332 Update README.md 2021-12-09 12:48:54 +08:00
young c6f6d4b964 Update README.md 2021-12-09 12:45:28 +08:00
young 08eccdcfb4 Update README.md 2021-12-09 12:43:08 +08:00
young 4a6c481126 Update README.md 2021-12-09 12:39:13 +08:00
young 2297477806 Update README.md 2021-12-09 12:33:05 +08:00
young 7bc167250f Update README.md 2021-12-09 12:32:07 +08:00
young afcb8c4ba5 Update README.md 2021-12-09 12:30:37 +08:00
young 028c38dc0d Update README.md 2021-12-09 12:29:27 +08:00
young 4a3d5b94fb Update README.md 2021-12-09 12:28:25 +08:00
yystopf 81e6691632 fix: educoder entries image file type 2021-12-09 11:33:43 +08:00
yystopf 38d6519381 fix 2021-12-09 11:08:54 +08:00
yystopf 16418675ac fix 2021-12-09 11:08:10 +08:00
yystopf 102858bc8c fix: educoder entries file use hash 2021-12-09 11:06:49 +08:00
yystopf 0d64768e4b fix: educoder file visit delay 2021-12-09 09:37:28 +08:00
young 07767c3c15 Update README.md 2021-12-08 20:21:55 +08:00
yystopf beccac652f fix 2021-12-08 18:25:31 +08:00
yystopf 30eb1958c1 fix 2021-12-08 18:23:29 +08:00
yystopf 33e17e8439 fix: educoder sub_entries and commit author 2021-12-08 18:18:19 +08:00
yystopf 5445206716 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-08 16:26:15 +08:00
yystopf 1c19c05fd8 fix 2021-12-08 16:26:06 +08:00
yystopf 957980fc71 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-08 16:23:21 +08:00
yystopf 657e2cf169 fix: merge from develop 2021-12-08 16:22:34 +08:00
yystopf e0c47c2abd fix: educoder clone url 2021-12-08 16:18:13 +08:00
xiaoxiaoqiong 9e64a4842d Merge branch 'standalone_develop' into pre_trustie_server 2021-12-08 15:32:47 +08:00
xiaoxiaoqiong ba9e74f373 fixed db:migrate 2021-12-08 15:32:28 +08:00
xxq250 93dd5b5d84 Merge pull request '易修声明功能' (#284) from starlee/forgeplus:lzx-claim-2.0 into standalone_develop 2021-12-08 15:12:15 +08:00
xiaoxiaoqiong b733f22cd6 前端build文件 2021-12-08 15:07:53 +08:00
yystopf 422549f9e7 fix 2021-12-08 15:01:33 +08:00
xiaoxiaoqiong c62065af12 Merge branch 'pre_trustie_server' into standalone 2021-12-08 15:01:10 +08:00
yystopf 0358229b95 fix: educoder api delay 2021-12-08 14:47:15 +08:00
yystopf c4586fbb36 fix: remove detail language and contributors 2021-12-08 14:11:37 +08:00
xxq250 a7f719c8bb Merge pull request 'Readme相关内容更新' (#279) from young/forgeplus:standalone into standalone 2021-12-07 17:07:49 +08:00
xiaoxiaoqiong 0a5a75dc0d Merge branch 'pre_trustie_server' into trustie_server 2021-12-07 17:03:32 +08:00
xiaoxiaoqiong d4ee468435 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-07 17:03:02 +08:00
xiaoxiaoqiong a26d8be0b0 fixed educode not owner 2021-12-07 17:02:35 +08:00
xiaoxiaoqiong f94006abfd fixed educode not owner 2021-12-07 16:59:04 +08:00
xiaoxiaoqiong 5618887e7a Merge branch 'pre_trustie_server' into trustie_server 2021-12-07 16:50:05 +08:00
xiaoxiaoqiong 3480e15c48 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-07 16:49:21 +08:00
xiaoxiaoqiong d85a446edc Merge branch 'develop' into standalone_develop 2021-12-07 16:48:52 +08:00
xiaoxiaoqiong 4d61e7618a fixed detail 2021-12-07 16:46:06 +08:00
xiaoxiaoqiong 9a8ddffb5a Merge branch 'pre_trustie_server' into trustie_server 2021-12-07 16:40:37 +08:00
xiaoxiaoqiong 2116af759d Merge branch 'standalone_develop' into pre_trustie_server 2021-12-07 16:40:18 +08:00
xiaoxiaoqiong 38862b9843 fixed owner 2021-12-07 16:40:01 +08:00
xiaoxiaoqiong f889849b6b Merge branch 'pre_trustie_server' into trustie_server 2021-12-07 16:35:05 +08:00
xiaoxiaoqiong 3501ff6bd4 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-07 16:34:29 +08:00
xiaoxiaoqiong badd950ff9 merge develop 2021-12-07 16:34:11 +08:00
xiaoxiaoqiong 8f70d4f604 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-07 16:32:33 +08:00
xiaoxiaoqiong 20bfbdc06f fixed owner 404 2021-12-07 16:32:14 +08:00
xiaoxiaoqiong b7bebcd736 Merge branch 'pre_trustie_server' into trustie_server 2021-12-07 16:28:47 +08:00
xiaoxiaoqiong d4663e410d Merge branch 'standalone_develop' into pre_trustie_server 2021-12-07 16:27:52 +08:00
xiaoxiaoqiong 1b385f4377 Merge branch 'standalone_develop' of https://git.trustie.net/Gitlink/forgeplus into standalone_develop 2021-12-07 16:27:25 +08:00
xiaoxiaoqiong 5c445b9ea0 merge develop 2021-12-07 16:27:17 +08:00
xiaoxiaoqiong 36286d9003 fixed:educode项目 2021-12-07 16:20:05 +08:00
yystopf f533a6253b Merge pull request '解决冲突,合并到测试环境' (#283) from yystopf/forgeplus:standalone_develop into standalone_develop 2021-12-07 14:41:37 +08:00
yystopf 0f9d33e755 merge from develop 2021-12-07 14:39:11 +08:00
yystopf 51356da7f3 fix: owners not return 404 2021-12-07 14:34:57 +08:00
yystopf ebe893022f fix: api doc logo 2021-12-07 14:34:57 +08:00
yystopf c5f22e6c70 fix: org delete status error 2021-12-07 14:34:57 +08:00
young 4144128cd1 Update README.md 2021-12-06 11:16:52 +08:00
young e1636bc665 Update README.md 2021-12-06 11:14:57 +08:00
young 4404d947fd Update README.md 2021-12-06 11:12:10 +08:00
young 66e01e9902 Update README.md 2021-12-06 10:59:49 +08:00
young 1502816374 Update README.md 2021-12-06 10:59:19 +08:00
young a1a866a308 Update README.md 2021-12-06 10:58:25 +08:00
Yang Zhang 79696ce7fc add pictures in readme 2021-12-06 10:55:05 +08:00
Yang Zhang 6badf203fb update readme 2021-12-06 10:48:48 +08:00
xiaoxiaoqiong 30135ccad7 Merge branch 'pre_trustie_server' into trustie_server 2021-12-01 17:45:31 +08:00
xiaoxiaoqiong eac97c6698 关闭项目精选筛选 2021-12-01 17:45:02 +08:00
xiaoxiaoqiong 8ee52440c7 关闭项目精选 2021-12-01 17:43:43 +08:00
xiaoxiaoqiong d9925db510 Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-12-01 17:23:38 +08:00
xiaoxiaoqiong 34bcf9ed57 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-01 17:21:54 +08:00
xiaoxiaoqiong b22c65e5c2 Merge branch 'develop' into standalone_develop 2021-12-01 17:21:23 +08:00
xiaoxiaoqiong 922561afb1 项目精选加索引 2021-12-01 17:20:52 +08:00
yystopf 6479ac8696 Merge pull request '生产环境js编译问题' (#277) from yystopf/forgeplus:hh_js_trustie_server into trustie_server 2021-12-01 16:32:12 +08:00
yystopf f4e4015a89 fix: production js compile 2021-12-01 16:29:58 +08:00
xiaoxiaoqiong cd4ba9c1d9 Merge branch 'standalone_develop' into pre_trustie_server 2021-12-01 10:05:37 +08:00
xiaoxiaoqiong f12b10fa23 merge 测试环境standalone_develop 2021-12-01 10:05:00 +08:00
yystopf 4a3275a15e Merge pull request '同步代码到预上线分支' (#276) from develop into standalone_develop 2021-12-01 10:03:26 +08:00
yystopf 6f7899d16f fix: create pr authorize tip 2021-11-30 20:23:37 +08:00
yystopf 24170fc2cb Merge pull request '同步通用代码到预上线' (#274) from develop into standalone_develop 2021-11-30 17:09:31 +08:00
yystopf 4e3c8e414c fix 2021-11-30 15:36:51 +08:00
yystopf d588a78f62 fix: locales for projects update form 2021-11-30 15:35:36 +08:00
yystopf a7d681c4dd fix: compare commit author image url 2021-11-30 15:03:55 +08:00
yystopf 7a93db9ed2 fix: labels limit and issues operate field 2021-11-30 13:58:51 +08:00
yystopf 74e5fa0e31 fix: fork project id validate 2021-11-29 17:01:39 +08:00
yystopf 80b83c5230 fix: index read api data use params only data 2021-11-29 16:40:24 +08:00
yystopf 6ffc702209 Merge pull request '提交最新代码到预上线环境' (#272) from develop into standalone_develop 2021-11-29 15:44:51 +08:00
yystopf de995c8714 fix: merge conflict 2021-11-29 15:43:47 +08:00
xiaoxiaoqiong 16f37a3729 email中logo 2021-11-29 15:35:54 +08:00
yystopf ea156cec7e fix: download type add video type 2021-11-29 15:33:09 +08:00
xiaoxiaoqiong f76df2c629 logo 2021-11-29 14:44:54 +08:00
yystopf 7499d8af89 fix: project private params to boolean 2021-11-29 14:43:29 +08:00
yystopf f8654edc3b fix: project labels return success info 2021-11-29 14:28:13 +08:00
yystopf d16f290aa6 fix: create pr validate fork_project_id 2021-11-29 14:17:27 +08:00
yystopf 9385d346f1 fix 2021-11-29 14:03:17 +08:00
yystopf 22f3371090 fix: change issues priority id default value 2021-11-29 11:05:33 +08:00
yystopf c0a4f8f4ec fix: create pull request need compare 2021-11-29 10:53:59 +08:00
yystopf 7586a0fb21 fix: change issue tag change size 2021-11-29 10:27:41 +08:00
yystopf c0e3a91a46 fix: page 500 2021-11-29 09:32:39 +08:00
xxq250 7c765817c9 Merge pull request 'merge develop to standalone_develop' (#267) from develop into standalone_develop 2021-11-26 14:21:53 +08:00
xiaoxiaoqiong 7ebd8681fa 500页面样式调整 2021-11-26 09:49:13 +08:00
xxq250 72553dec57 Merge pull request '一些功能修改以及bug修复' (#263) from yystopf/forgeplus:hh_hotfix into develop 2021-11-26 09:39:58 +08:00
yystopf dee68808b1 fix 2021-11-25 17:37:05 +08:00
yystopf 96d7917bbf fix: change 500 html 2021-11-25 17:34:21 +08:00
yystopf abca0fe432 fix: change pr path id to number 2021-11-25 15:08:59 +08:00
yystopf d7612a0921 add: create update pr need authorize 2021-11-25 14:16:45 +08:00
yystopf c54950a95f fix: compare params contain .json 2021-11-25 14:06:55 +08:00
starlee e25e2fdd77 add the claim mechanism 2021-11-25 13:33:32 +08:00
yystopf be0f68cede fix 2021-11-25 11:19:50 +08:00
yystopf 1b92b53099 fix 2021-11-25 11:00:19 +08:00
yystopf 5634413cac add: create pullrequest validate 2021-11-25 10:52:42 +08:00
xxq250 1eb1d25040 Merge pull request 'README文件中的图片显示问题' (#262) from xxq250/forgeplus:fix_issue_xxq into standalone_develop 2021-11-25 10:41:00 +08:00
xiaoxiaoqiong a4a431e9bb Merge branch 'standalone_develop' of https://git.trustie.net/Gitlink/forgeplus into fix_issue_xxq 2021-11-25 10:31:52 +08:00
xiaoxiaoqiong 515307139a README文件中的图片显示问题 2021-11-25 10:30:46 +08:00
xxq250 0a3df09089 Merge pull request '验证码过期等#53446,#50806,#50880' (#260) from xxq250/forgeplus:fix_issue_xxq into standalone_develop 2021-11-24 18:17:13 +08:00
xiaoxiaoqiong 399558550e fix 验证码过期等#53446,#50806,#50880 2021-11-24 18:13:15 +08:00
yystopf 1a9ed1425e fix: destroy decrement forked count 2021-11-23 13:48:09 +08:00
yystopf f9d4316a8e fix: change fork project status 2021-11-23 11:43:44 +08:00
yystopf 6f7f815fd4 fix: change warn image 2021-11-19 15:15:40 +08:00
yystopf ddb826733b fix: project setting permission control 2021-11-19 14:56:20 +08:00
yystopf 1f989d0a37 fix: delete organization tip 2021-11-19 14:44:25 +08:00
yystopf 72ec7bc213 fix: change email default rule 2021-11-19 10:57:25 +08:00
yystopf d63626424e Merge pull request '更改邮件默认发送规则' (#251) from yystopf/forgeplus:hh_email_fix into develop 2021-11-19 10:38:04 +08:00
yystopf 55ab694505 fix: change email default rule 2021-11-19 10:21:09 +08:00
yystopf 0885575cc4 fix: organization validate name tip 2021-11-18 17:31:22 +08:00
yystopf a188648287 fix: qq qun url 2021-11-18 17:25:50 +08:00
yystopf 8011dabaac fix: undo events 2021-11-18 17:02:09 +08:00
yystopf 88a08e73c0 fix: web icon 2021-11-18 16:13:33 +08:00
yystopf 6713f9b280 fix: pullrequest trend action name 2021-11-17 11:04:15 +08:00
jasder 7a37a32eee Merge branch 'standalone' of https://git.trustie.net/Gitlink/forgeplus into standalone 2021-11-14 21:15:39 +08:00
jasder 16bfd3b2e3 Merge branch 'standalone_develop' into standalone 2021-11-14 21:15:18 +08:00
jasder 651bf34cfc FIX code review and conflict 2021-11-14 20:50:22 +08:00
jasder cc3de099fe Merge pull request '修复readme文件中的错别字' (#247) from starlee/forgeplus:standalone into standalone 2021-11-14 20:36:07 +08:00
starlee 8bfe421eaa fix a typo in README 2021-11-12 09:06:15 +08:00
jasder 3a7355c73e Merge pull request 'fix 合并独立版本代码' (#242) from jasder/forgeplus:standalone_develop into standalone_develop 2021-11-08 15:12:01 +08:00
jasder 77ad959a8c Merge remote-tracking branch 'gitlink/featrue_login_and_register' into standalone_develop 2021-11-08 15:08:47 +08:00
jasder 9d05973700 FIX 解决featrue_homepage分支代码冲突 2021-11-08 15:07:35 +08:00
jasder 7ad3789fe2 FIX 解决develop分支代码冲突 2021-11-08 14:59:06 +08:00
jasder 7ebfaf915f ADD 添加react build文件 2021-11-08 14:52:45 +08:00
jasder e3588291b2 Merge pull request '首页api数据以及后台管理' (#240) from yystopf/forgeplus:hh_home_index into featrue_homepage 2021-11-08 14:35:19 +08:00
jasder 7a14949063 Merge pull request 'fix 修复验证无效的bug' (#237) from jasder/forgeplus:featrue_login_and_register into featrue_login_and_register 2021-11-05 09:04:55 +08:00
jasder 8d3b674321 FIX viri code invalid bug 2021-11-04 14:14:11 +08:00
jasder 2ece9908a6 Merge pull request 'FIX [gitea] reset pw bug' (#236) from jasder/forgeplus:featrue_login_and_register into featrue_login_and_register 2021-11-04 09:29:19 +08:00
jasder a549dc1e25 FIX reset password bug 2021-11-03 21:32:17 +08:00
jasder 6607758c25 Merge branch 'featrue_login_and_register' of https://git.trustie.net/Gitlink/forgeplus into featrue_login_and_register 2021-11-03 20:50:45 +08:00
jasder e02237a9e0 FIX code review 2021-11-03 18:25:57 +08:00
jasder 59711b54bc Merge pull request 'fix 完善重置密码功能' (#235) from jasder/forgeplus:featrue_login_and_register into featrue_login_and_register 2021-11-03 17:21:18 +08:00
jasder 538d2113f1 FIX 完善重置密码功能 2021-11-03 17:19:43 +08:00
yystopf 18cf2ca78a fix 2021-11-03 14:26:19 +08:00
yystopf 0d1fa2995a fix 2021-11-03 14:25:04 +08:00
yystopf e243a61d0c add: request api data and topic group 2021-11-03 14:21:02 +08:00
jasder 06cf52c384 ADD 注册接口添加确认密码参数 2021-11-03 13:50:38 +08:00
yystopf a3f57d3cbc fix: paginate and img width 2021-11-03 11:38:47 +08:00
yystopf 18bbbce7b3 add: home index api 2021-11-03 10:19:01 +08:00
jasder 8d60b271f7 Merge branch 'featrue_login_and_register' of https://git.trustie.net/Gitlink/forgeplus into featrue_login_and_register 2021-11-02 21:43:50 +08:00
jasder be96e7e5eb FIX render_error mentod bug 2021-11-02 21:43:10 +08:00
yystopf 35f04afe91 add: home index admins 2021-11-02 19:00:07 +08:00
yystopf 385f45ddde add: home index controllers 2021-11-02 15:59:57 +08:00
yystopf 94075717e2 add: home index models 2021-11-02 15:56:47 +08:00
jasder a033ddeeca Merge pull request 'FIX update register api' (#232) from jasder/forgeplus:featrue_login_and_register into featrue_login_and_register 2021-11-02 13:49:57 +08:00
jasder 7b5452fdcc Merge pull request 'FIX 合并测试版分支代码' (#229) from dev_trustie_server into trustie_server 2021-10-29 15:10:01 +08:00
jasder b40cbfbfbb FIX conflict 2021-10-29 15:07:01 +08:00
jasder 5d68b051db Merge branch 'develop' into standalone 2021-10-25 17:25:08 +08:00
jasder f2bee32eec Merge pull request 'ADD hompage' (#219) from jasder/forgeplus:standalone into standalone 2021-10-22 14:55:08 +08:00
jasder 21de628c11 FIX 集成平台首页功能 2021-10-22 14:53:09 +08:00
jasder 0fc00da95f Merge pull request 'fix css、icon bug' (#218) from jasder/forgeplus:standalone into standalone 2021-10-22 14:19:45 +08:00
jasder 41022950a5 FIX 解决icon样式问题 2021-10-22 14:17:36 +08:00
jasder a7caca7210 Merge pull request 'FIX 提交前端页面代码' (#217) from jasder/forgeplus:standalone into standalone 2021-10-22 11:56:14 +08:00
jasder d9e4f26819 ADD 前端页面打包文件 2021-10-22 11:52:01 +08:00
jasder 6782380ff7 Merge pull request 'fix merge remote standalone branch' (#216) from jasder/forgeplus:standalone into standalone 2021-10-22 11:19:57 +08:00
jasder 683c00a73e Merge branch 'trustie_server' into standalone 2021-10-22 11:16:30 +08:00
jasder 74a7bc62ea FIX 合并develop分支代码并处理冲突 2021-10-22 11:16:22 +08:00
jasder a5e5dbb6bf Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-10-22 10:52:42 +08:00
jasder da30ba189c Merge pull request '主干分支代码并入生产分支' (#215) from dev_trustie_server into trustie_server 2021-10-21 15:06:40 +08:00
jasder b5047392a6 Merge pull request '合并主干分支代码' (#214) from jasder/forgeplus:dev_trustie_server into dev_trustie_server 2021-10-21 14:45:58 +08:00
jasder 5b19a333ef Merge branch 'develop' into dev_trustie_server 2021-10-21 14:41:43 +08:00
yystopf 62e8cf76b9 Merge pull request 'ADD 通知公告以及修复bug' (#207) from dev_trustie_server into trustie_server 2021-10-18 18:27:06 +08:00
jasder 33a5b7f4f9 FIX 合并主干分支代码并解决代码冲突 2021-10-18 18:16:12 +08:00
jasder 4567c32b97 Merge pull request 'FIX edit project identifier’s bug' (#201) from dev_trustie_server into trustie_server 2021-10-15 16:57:20 +08:00
jasder 9899a8aab6 Merge pull request 'FIX edit project identifier’s bug' (#200) from develop into dev_trustie_server 2021-10-15 16:56:43 +08:00
jasder da3625a0a8 Merge pull request 'FIX 项目动态数据修复以及 Pr项目链接错误的bug' (#198) from dev_trustie_server into trustie_server 2021-10-15 16:32:49 +08:00
jasder 6f5f42c23a Merge pull request 'FIX dev_trustie_server 远程仓库pr' (#197) from jasder/forgeplus:dev_trustie_server into dev_trustie_server 2021-10-15 16:22:02 +08:00
jasder 3c44ffe7df Merge remote-tracking branch 'gitlink/dev_trustie_server' into dev_trustie_server 2021-10-15 16:13:45 +08:00
jasder 4ebb6a5e74 Merge branch 'develop' into dev_trustie_server 2021-10-15 16:09:48 +08:00
jasder 5cbe83f9d4 Merge pull request 'FIX WIP' (#192) from dev_trustie_server into trustie_server 2021-10-14 18:13:26 +08:00
jasder 7030e0b5bc Merge pull request 'FIX some bug' (#191) from develop into dev_trustie_server 2021-10-14 18:12:36 +08:00
jasder 01377bc20a Merge pull request 'FIX 修复pr链接问题' (#189) from dev_trustie_server into trustie_server 2021-10-14 15:41:46 +08:00
jasder 976c4b26c3 Merge pull request 'FIX 修复Pr链接错误问题' (#188) from develop into dev_trustie_server 2021-10-14 15:41:06 +08:00
jasder d5e9005253 Merge branch 'trustie_server' of https://git.trustie.net/Gitlink/forgeplus into trustie_server 2021-10-12 18:40:05 +08:00
jasder f01bfe6435 Merge pull request 'Merge' (#181) from dev_trustie_server into trustie_server 2021-10-12 18:39:48 +08:00
jasder 1f451779de Merge pull request 'FIX' (#180) from develop into dev_trustie_server 2021-10-12 18:38:58 +08:00
jasder c4c3a451c8 Merge branch 'trustie_server' of https://git.trustie.net/jasder/forgeplus into trustie_server 2021-10-12 14:18:19 +08:00
jasder ac6aa7559d Merge pull request 'FIX 合并测试版分支的代码' (#177) from dev_trustie_server into trustie_server 2021-10-12 14:12:33 +08:00
jasder 829e36cfce Merge pull request 'FIX remote pr' (#176) from jasder/forgeplus:dev_trustie_server into dev_trustie_server 2021-10-12 14:09:05 +08:00
jasder fb73fa458c Merge pull request 'FIX 解决合并请求中链接地址错误的问题' (#2) from dev_trustie_server into trustie_server 2021-10-12 14:06:20 +08:00
jasder 7c8843fda7 Merge branch 'develop' into dev_trustie_server 2021-10-12 14:02:33 +08:00
jasder 40654061ce Merge pull request 'FiX 发布生产版本' (#173) from dev_trustie_server into trustie_server 2021-10-09 16:17:27 +08:00
jasder 3325ec842d Merge pull request 'FIX 代码库二级页面改版以及其他bug' (#172) from develop into dev_trustie_server 2021-10-09 16:15:12 +08:00
jasder 194a2f4e36 Merge pull request 'FIX user info bug' (#166) from dev_trustie_server into trustie_server 2021-09-29 11:43:29 +08:00
jasder bd1cd7ee13 Merge pull request 'FIX user complete bug' (#165) from develop into dev_trustie_server 2021-09-29 11:42:48 +08:00
jasder fdbc657846 Merge pull request 'add 通知系统模块功能' (#163) from dev_trustie_server into trustie_server 2021-09-28 16:44:29 +08:00
jasder 317205d185 Merge branch 'develop' into dev_trustie_server 2021-09-28 15:59:51 +08:00
jasder 14949c0bfd ADD 通知系统模块代码 2021-09-28 15:59:06 +08:00
jasder 0cbfc895ca Merge pull request 'FIX 修复修改组织信息后导致不能创建项目的bug' (#152) from dev_trustie_server into trustie_server 2021-09-10 22:52:12 +08:00
jasder 2fab120118 Merge pull request 'FIX 修复修改组织信息后导致不能创建项目的bug' (#151) from develop into dev_trustie_server 2021-09-10 22:51:18 +08:00
jasder 629729436c Merge pull request 'FIX 优化创建项目流程' (#149) from dev_trustie_server into trustie_server 2021-09-10 19:03:26 +08:00
jasder 00ed177089 Merge pull request 'FIX bug' (#148) from develop into dev_trustie_server 2021-09-10 18:32:08 +08:00
jasder 26c0d36227 Merge pull request 'FIX 优化项目流程' (#146) from develop into dev_trustie_server 2021-09-10 18:28:36 +08:00
jasder 86c98a1716 Merge pull request '发布V3.1.0版本' (#139) from dev_trustie_server into trustie_server 2021-09-03 18:16:51 +08:00
jasder 143e88593f Merge pull request 'FIX 路由优化' (#138) from develop into dev_trustie_server 2021-09-03 17:55:43 +08:00
jasder 99e3aaf780 Merge pull request 'merge dev_trustie_server' (#134) from dev_trustie_server into trustie_server 2021-09-01 19:02:51 +08:00
jasder 7d12a25088 Merge pull request 'FIX commit user info' (#133) from develop into dev_trustie_server 2021-09-01 19:01:22 +08:00
jasder 85d1aa3a85 Merge pull request 'fix release v3.2.0' (#129) from dev_trustie_server into trustie_server 2021-08-27 15:28:22 +08:00
jasder 0f57844106 Merge pull request 'FIX some bug' (#128) from develop into dev_trustie_server 2021-08-27 15:12:27 +08:00
jasder c3b9d2e0b5 ADD wiki模块功能 2021-08-24 18:17:34 +08:00
jasder 299e8534d1 Merge branch 'develop' into dev_trustie_server 2021-08-19 17:48:31 +08:00
jasder d7362925f2 Merge branch 'dev_trustie_server' into trustie_server 2021-08-06 17:24:02 +08:00
jasder 43945b00b8 Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-08-06 17:20:44 +08:00
jasder b11d515ec6 Merge branch 'develop' into dev_trustie_server 2021-08-06 17:20:30 +08:00
yystopf 07a38ac3f7 Merge branch 'develop' into dev_trustie_server 2021-07-30 18:12:19 +08:00
yystopf 18227c232b Merge branch 'develop' into trustie_server 2021-07-30 18:10:31 +08:00
jasder f1d79e4d9f Merge branch 'trustie_server' of https://git.trustie.net/jasder/forgeplus into trustie_server 2021-07-30 17:08:42 +08:00
jasder 20e2e22be5 Merge branch 'dev_trustie_server' into trustie_server 2021-07-30 17:08:23 +08:00
jasder 27e5febef2 Merge branch 'develop' into dev_trustie_server 2021-07-30 17:04:21 +08:00
yystopf fb23e733d6 Merge branch 'develop' into dev_trustie_server 2021-07-23 17:23:45 +08:00
yystopf 512bff426d Merge branch 'develop' into trustie_server 2021-07-23 17:23:29 +08:00
yystopf 671c2c2257 Merge branch 'develop' into trustie_server 2021-07-23 14:53:18 +08:00
yystopf c6f2021017 Merge branch 'develop' into dev_trustie_server 2021-07-23 14:53:06 +08:00
jasder 581b147b3c Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-07-23 14:16:43 +08:00
jasder deebfc3292 fix merge develop branch 2021-07-23 14:16:29 +08:00
yystopf 6c4d17bed8 Merge branch 'develop' into trustie_server 2021-07-22 18:31:44 +08:00
yystopf e68c13f1a2 Merge branch 'develop' into dev_trustie_server 2021-07-22 18:30:59 +08:00
yystopf 15eb1f4a17 Merge branch 'develop' into dev_trustie_server 2021-07-21 21:32:38 +08:00
yystopf a1cb9a11d6 Merge branch 'develop' into trustie_server 2021-07-21 21:32:18 +08:00
yystopf 0884a0de1b Merge branch 'develop' into dev_trustie_server 2021-07-16 16:46:28 +08:00
yystopf 900fdd2691 Merge branch 'develop' into trustie_server 2021-07-16 16:46:08 +08:00
viletyy 4520055de2 Merge branch 'dev_trustie_server' into trustie_server 2021-07-12 18:38:03 +08:00
viletyy 193d1b21df Merge branch 'develop' into dev_trustie_server 2021-07-12 18:10:50 +08:00
viletyy ed8e079595 Merge branch 'develop' into dev_trustie_server 2021-07-12 17:57:51 +08:00
viletyy 55a0bcfb82 fix 2021-07-12 17:33:10 +08:00
viletyy 8f1aa3f4b1 fix: merge from develop 2021-07-12 17:28:47 +08:00
jasder b054094798 FIX conflicts 2021-07-12 16:20:14 +08:00
jasder 2d648e516e FIX merge develop branch 2021-07-12 16:19:03 +08:00
yystopf 7c23b40661 易修权限、用户更改昵称、fork项目修改项目私有性 2021-07-09 13:55:22 +08:00
viletyy ff21916f18 fix: merge from develop 2021-07-09 13:48:48 +08:00
viletyy d9162cb3bf fix: merge from develop 2021-07-09 13:47:21 +08:00
jasder ca1fd3cd4f FIX 解决标签列表和发行版列表中下周zip包、tar包导致的404问题 2021-07-01 16:57:52 +08:00
jasder 913bc45a9f Merge branch 'dev_trustie_server' of https://git.trustie.net/jasder/forgeplus into dev_trustie_server 2021-07-01 10:09:28 +08:00
jasder 8131d8cd48 Merge branch 'sync_develop' into dev_trustie_server 2021-07-01 10:08:58 +08:00
viletyy b45ab12279 Merge branch 'dev_trustie_server' into trustie_server 2021-06-28 21:11:13 +08:00
viletyy 259090b8e3 fix 2021-06-28 21:07:10 +08:00
jasder c3bc4166d9 FIX pr bug
ADD conflict files list
2021-06-28 10:09:40 +08:00
jasder 7e474cab70 Merge branch 'feature/pull_conflict_files' into dev_trustie_server 2021-06-28 10:06:54 +08:00
jasder 01341d4389 FIX pull、 gitea pull model relation bug 2021-06-28 10:04:48 +08:00
jasder 3a475a4674 FIX get conflict files bug with create pr api 2021-06-28 09:59:47 +08:00
jasder 83b7b8cd9c Merge branch 'develop' into dev_trustie_server 2021-06-25 18:03:28 +08:00
jasder c298ff02b8 ADD pr冲突文件展示 2021-06-25 18:03:07 +08:00
jasder 16ea03dcc8 fix 修复一些bug
* 解决获取平台base url导致的https的问题
* FIX 处理版本库zip、gzip包链接为无效的问题
2021-06-22 16:49:20 +08:00
jasder 7bb4cf7391 Merge branch 'develop' into dev_trustie_server 2021-06-22 15:15:51 +08:00
jasder 23f7439a8c Merge branch 'develop' into dev_trustie_server 2021-06-22 09:51:46 +08:00
jasder 6f19093dc2 FIX merge develop flick 2021-06-18 17:23:48 +08:00
jasder fa8f1155f5 V3.1.0
* FIX 修复pulls、issues 搜索数量统计问题
* FIX 解决在线创建文件错误提示信息不准确的问题
* FIX table name bug
* FIX 解决applied_projects相关表操作的问题
* FIX 解决排序参数的判断预防SQL注入
* FIX 项目导航栏数量改为开启中的数量
* FIX 解决项目邀请码的索引查询问题
* FIX FIX get readme file bug
* FIX sql attack
* FIX projects load by invite code slowly
2021-06-18 17:03:27 +08:00
jasder 484f8a854a Merge branch 'develop' into dev_trustie_server 2021-06-18 16:45:12 +08:00
jasder 7bedac263d Merge branch 'develop' into dev_trustie_server 2021-06-18 16:21:21 +08:00
jasder f0b1c9e80b Merge branch 'develop' into dev_trustie_server 2021-06-18 11:03:41 +08:00
jasder dc23be9001 Merge branch 'develop' into dev_trustie_server 2021-06-18 10:54:29 +08:00
jasder e24269c2a7 Merge branch 'develop' into dev_trustie_server 2021-06-17 18:14:19 +08:00
jasder e31176c696 ADD 项目邀请码功能 2021-06-11 18:13:33 +08:00
jasder bf390c8366 Merge branch 'develop' into dev_trustie_server 2021-06-11 18:03:35 +08:00
jasder fc60278f9a FIX * ENHANCEMENTS
* ADD 用户活动统计图表功能
  * ADD 用户精选项目功能
  * ADD 用户贡献度统计图表功能
  * ADD 用户开发能力数据统计工
  * ADD 用户角色定位展示功能
  * ADD 用户专业定位标签展示功能
  * ADD 修改用户基本资料功能
  * ADD 更改密码功能
  * ADD 用户个人主页基本现在展示可配置功能

* BUGFIXES
  * Fix 解决一些bug
  * Fix 优化美化页面change license
2021-06-09 17:52:57 +08:00
jasder b59376d3e3 Merge branch 'master' into standalone 2021-06-09 17:49:52 +08:00
jasder c5d73b7cf8 v3.1.0
* 改版升级个人主页
* 修复bug
* 更改license
2021-06-09 09:52:57 +08:00
jasder 632a06e575 Merge branch 'develop' into dev_trustie_server 2021-06-08 18:13:16 +08:00
jasder 04c7887319 Merge branch 'sync_develop' into dev_trustie_server 2021-06-08 14:34:29 +08:00
jasder b012740195 ADD 升级改版个人中心模块功能 2021-06-04 19:10:07 +08:00
jasder d75b79670d Merge branch 'develop' into dev_trustie_server 2021-06-04 18:51:47 +08:00
jasder 0f79238f0e 解决镜像加速器失效问题 2021-06-03 17:29:37 +08:00
jasder 2c5fa8492f Merge branch 'develop' into dev_trustie_server 2021-06-03 17:26:35 +08:00
jasder fdfbf505ed ADD issue、pull、milestone钩子,自动触发项目的更新时间 2021-05-26 17:52:30 +08:00
jasder 6d845eeb3b Merge branch 'develop' into dev_trustie_server 2021-05-26 17:39:54 +08:00
jasder a7695b16a4 FIX query project members api bug 2021-05-24 17:08:03 +08:00
jasder 83e666a387 Merge branch 'develop' into dev_trustie_server 2021-05-24 17:06:54 +08:00
jasder 1a0fd38d15 发布v3.0.4版本 2021-05-24 10:18:57 +08:00
jasder 8a10a183e0 Merge branch 'develop' 2021-05-24 10:18:03 +08:00
jasder 5eaaf0070f FIX update CHANGELOG.md 2021-05-24 10:13:14 +08:00
jasder aeeaedbd7a Merge branch 'develop' into standalone 2021-05-24 10:11:02 +08:00
jasder 6d1bcabd51 Merge branch 'master' of https://git.trustie.net/jasder/forgeplus 2021-05-24 10:10:24 +08:00
jasder 72b89d4b2b Merge branch 'develop' into dev_trustie_server 2021-05-21 19:26:47 +08:00
jasder b0b224fe76 Merge branch 'trustie_server' of https://git.trustie.net/jasder/forgeplus into trustie_server 2021-05-15 10:21:03 +08:00
jasder 38f6254edc Merge branch 'develop' into dev_trustie_server 2021-05-15 10:20:14 +08:00
jasder 57d9da002e ADD 页面置顶等功能 2021-05-14 17:57:48 +08:00
jasder 8a4b0ba966 Merge branch 'develop' into dev_trustie_server 2021-05-14 17:34:36 +08:00
jasder 84927c2361 FIX 解决大赛中点击项目跳转到forge平台,保持自动登陆的bug 2021-05-13 11:47:47 +08:00
jasder b568ac4e97 ADD title 2021-05-12 17:48:05 +08:00
jasder 91bbb58d4f FIX delete input readonly 2021-05-12 17:44:45 +08:00
jasder f278b38e6c Merge branch 'trustie_server' into dev_trustie_server 2021-05-12 17:01:59 +08:00
jasder 4023b8980e FIX 完善通过大赛点击项目链接自动注册关联Educoder平台账号的功能 2021-05-12 17:01:30 +08:00
jasder 1c1be18151 Merge branch 'dev_trustie_server' into trustie_server 2021-05-10 14:39:14 +08:00
jasder e5f591e509 Merge branch 'develop' into dev_trustie_server 2021-05-10 14:38:58 +08:00
jasder 60b22b3912 Merge develop 2021-05-08 18:16:45 +08:00
jasder 86f03ffafc Merge OK 2021-05-08 17:46:22 +08:00
yystopf 27ee32054b 发布v3.0.3版本 2021-05-08 17:45:23 +08:00
jasder 3e3fd46cad Merge branch 'develop' into dev_trustie_server 2021-05-08 17:02:56 +08:00
jasder 7a752b177d Merge branch 'develop' into dev_trustie_server 2021-05-08 14:23:34 +08:00
jasder abbabfdefd Merge branch 'dev_trustie_server' into trustie_server 2021-04-30 17:13:33 +08:00
jasder edd76b9286 Merge branch 'develop' into dev_trustie_server 2021-04-30 17:13:18 +08:00
jasder a3ca94d433 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 23:23:55 +08:00
jasder 91a804caf7 Merge branch 'develop' into dev_trustie_server 2021-04-29 23:23:42 +08:00
jasder 663deae21b Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 23:19:34 +08:00
jasder dae5c9690f Merge branch 'develop' into dev_trustie_server 2021-04-29 23:19:17 +08:00
jasder e65df07d79 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 19:27:55 +08:00
jasder 246b6b52ec Merge branch 'develop' into dev_trustie_server 2021-04-29 19:27:36 +08:00
jasder b9789183e3 Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 19:17:03 +08:00
jasder 7cf2c6021f Merge branch 'develop' into dev_trustie_server 2021-04-29 19:13:12 +08:00
jasder e0f9a3d43d Merge branch 'develop' into dev_trustie_server 2021-04-29 18:50:11 +08:00
jasder c1ef39b262 Merge branch 'develop' into dev_trustie_server 2021-04-29 18:37:35 +08:00
jasder 51643dc02c Merge branch 'dev_trustie_server' into trustie_server 2021-04-29 10:42:12 +08:00
jasder a078c07b59 Merge branch 'develop' into dev_trustie_server 2021-04-29 10:41:59 +08:00
jasder b984790d5c Merge branch 'develop' into trustie_server 2021-04-28 21:17:43 +08:00
jasder 876591100e Merge branch 'develop' into dev_trustie_server 2021-04-28 21:17:36 +08:00
jasder ba9848ebe7 Merge branch 'develop' into dev_trustie_server 2021-04-27 18:24:41 +08:00
jasder 41c621cf55 Merge branch 'develop' into dev_trustie_server 2021-04-26 16:53:05 +08:00
jasder 09ac49dda5 Merge branch 'develop' into dev_trustie_server 2021-04-26 16:46:24 +08:00
jasder b161b66d79 Merge branch 'develop' into standalone 2021-04-23 17:55:42 +08:00
jasder 341a810afc Merge branch 'develop' into dev_trustie_server 2021-04-23 17:54:13 +08:00
jasder 2282c52efb FIX update README.md 2021-04-23 17:33:19 +08:00
jasder 34edd78ae7 Merge branch 'develop' into dev_trustie_server 2021-04-23 17:21:34 +08:00
jasder 8a536e83af FIX update CHANGELOG.md 2021-04-23 17:08:04 +08:00
jasder 016cf648da FIX merge develop 2021-04-23 17:07:46 +08:00
jasder 713e0bba18 Merge branch 'develop' into standalone 2021-04-23 16:18:31 +08:00
jasder 36fb5a118c Merge branch 'develop' into dev_trustie_server 2021-04-23 14:40:41 +08:00
jasder b756be1d6a Merge branch 'develop' into dev_trustie_server 2021-04-22 18:10:32 +08:00
jasder 348c2244f7 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:45:40 +08:00
jasder 31738fc227 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:43:04 +08:00
jasder a93c98fb7c Merge branch 'trustie_server' into dev_trustie_server 2021-04-22 16:39:03 +08:00
jasder 39193324e9 Merge branch 'develop' into dev_trustie_server 2021-04-22 16:38:58 +08:00
jasder 81743ce3bc Merge branch 'develop' into trustie_server 2021-04-20 19:07:56 +08:00
jasder e9ae536f04 Merge branch 'develop' into trustie_server 2021-04-20 19:06:40 +08:00
jasder 186955fe4a Merge branch 'develop' into trustie_server 2021-04-20 18:58:24 +08:00
jasder 8ce7fd95cb Merge branch 'develop' into trustie_server 2021-04-20 18:37:55 +08:00
jasder 0867e5130f Merge branch 'dev_trustie_server' into trustie_server 2021-04-20 11:37:25 +08:00
jasder db476a1a9b Merge branch 'develop' into dev_trustie_server 2021-04-20 11:37:08 +08:00
jasder fa1fd8a4ba Merge branch 'develop' into trustie_server 2021-04-19 20:39:29 +08:00
jasder 0d7a11f3ab Merge branch 'develop' into dev_trustie_server 2021-04-19 18:41:18 +08:00
jasder 879e45e106 Merge branch 'develop' into trustie_server 2021-04-13 16:40:23 +08:00
jasder b3b0f75e9b Merge branch 'develop' into trustie_server 2021-04-13 10:18:52 +08:00
jasder 3af75e1a1c FIX merge develop branch 2021-04-13 10:18:35 +08:00
jasder 5c8e561bd8 Merge branch 'develop' into trustie_server 2021-04-08 18:36:27 +08:00
jasder 2b0c987558 Merge branch 'develop' into trustie_server 2021-04-07 11:35:09 +08:00
jasder 6796805b21 Merge branch 'develop' into trustie_server 2021-04-02 18:58:08 +08:00
jasder 5752f19b2f FIX gug 2021-04-02 18:56:44 +08:00
jasder eb52f05417 集成educoder登陆 2021-04-02 18:46:15 +08:00
vilet.yy 786629dbff fix 2021-04-02 18:41:48 +08:00
vilet.yy 7a00541375 Merge branch 'develop' into hh_develop 2021-04-02 18:41:37 +08:00
vilet.yy 1d832a1723 fix 2021-04-02 18:38:08 +08:00
vilet.yy 80ce40e492 fix 2021-04-02 18:33:31 +08:00
vilet.yy 91f6dae56a fix 2021-04-02 18:24:20 +08:00
vilet.yy 8c5a834b14 Merge branch 'develop' into hh_develop 2021-04-02 18:22:32 +08:00
vilet.yy 57f420848e Merge branch 'develop' into hh_develop 2021-04-02 18:20:41 +08:00
vilet.yy fba58800a7 fix 2021-04-02 18:08:36 +08:00
vilet.yy c4a43c4392 add: need edit user password 2021-04-02 16:44:36 +08:00
vilet.yy 1153bd5ab6 fix: set redirect_uri 2021-04-02 09:43:18 +08:00
vilet.yy f732b0374c fix: ceshi 2021-04-02 09:23:11 +08:00
jasder 0852d0ac61 Merge branch 'standalone' of https://git.trustie.net/jasder/forgeplus into standalone 2021-04-01 20:33:42 +08:00
jasder ee5090de96 Merge branch 'develop' into standalone 2021-04-01 20:33:26 +08:00
vilet.yy 0d97d7d4f0 add: educoder third party 2021-04-01 18:01:51 +08:00
jasder 37005342ab ADD friste register user set admin role 2021-03-31 15:28:23 +08:00
jasder 9591c0a82a Merge branch 'develop' into standalone 2021-03-31 15:02:26 +08:00
jasder ffee782591 Merge branch 'develop' into standalone 2021-03-31 13:35:59 +08:00
jasder c55c04b137 Merge branch 'standalone' of https://git.trustie.net/jasder/forgeplus into standalone 2021-03-31 12:45:09 +08:00
jasder 049e5a6d5f Merge branch 'develop' into standalone 2021-03-31 12:44:52 +08:00
jasder be6bb690d2 FIX models schema 2021-03-31 11:21:36 +08:00
jasder 7c2aa2209d delete helps sidebar 2021-03-31 11:21:09 +08:00
jasder a56ee23224 update db structrue 2021-03-31 11:20:42 +08:00
jasder fc95fe9b82 Merge branch 'develop' into standalone 2021-03-31 10:30:57 +08:00
jasder 838fd8b4c9 Merge branch 'develop' into standalone 2021-03-31 10:08:53 +08:00
jasder 8ca1311626 FIX delete generate api doc 2021-03-30 15:20:23 +08:00
jasder 869750e774 FIX delete readme for create gitea repo 2021-03-30 14:19:42 +08:00
970 changed files with 110744 additions and 19498 deletions

2
.gitignore vendored
View File

@ -37,13 +37,11 @@ public/react/yarn.lock
# Ignore react node_modules
public/system/*
public/react/*
/public/react/.cache
/public/react/node_modules/
/public/react/config/stats.json
/public/react/stats.json
/public/react/.idea/*
/public/react/build/*
/public/h5build
/public/npm-debug.log

View File

@ -23,7 +23,7 @@
* Fix 版本库中附件下载400(#51625)
* Fix loading页面优化(#51588)
* Fix 提交详情页面优化(#51577)
* Fix 修复修复制功能(#51569)
* Fix 修复修复制功能(#51569)
* Fix 修复新建发行版用户信息显示错误的问题(#51665)
* Fix 修复查看文件详细信息报错的问题(#51561)
* Fix 修复提交记录中时间显示格式问题(#51526)
@ -62,7 +62,7 @@
## [v3.0.3](https://forgeplus.trustie.net/projects/jasder/forgeplus/releases) - 2021-05-08
* BUGFIXES
* Fix 解决修标题过长导致的排版问题(45469)
* Fix 解决修标题过长导致的排版问题(45469)
* Fix 解决合并请求详情页面排版错误的问题(45457)
* FIX 解决转移仓库界面专有名词描述错误的问题(45455)
* Fix 解决markdown格式文件自动生成数字排序的问题(45454)

143
README.md
View File

@ -1,17 +1,30 @@
Trustie (确实)是一个以大众化协同开发、开放式资源共享、持续性可信评估为核心机理,面向高校创新实践的在线协作平台。
# GitLink - CCF开源创新服务平台
## 特性
GitLink确实开源是中国计算机学会CCF官方指定的开源创新服务平台旨在以“为开源创新服务”为使命以“成为开源创新的汇聚地”为愿景秉承“创新、开放、协作、共享”的价值观致力于为大规模开源开放协同创新助力赋能打造创新成果孵化和新工科人才培养的开源创新生态
- 软件创作与生产深度融合的软件开发环境体系结构 软件自由创作和工程生产的高效衔接,适于软件开发中群体智慧的有效汇聚。
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/gitlink.png?raw=true" width=80% />
</center>
## 特色功能
- 构件化协同开发环境的可扩展运行框架多样化工具的集成和联动,形成了强动态扩展能力的平台框架。
- **分布式协作开发**基于Git打造分布式代码托管环境提供免费公、私有代码仓库支持在线文件编辑、代码分支管理、协作贡献统计、代码仓库复刻Fork、贡献合并请求PR、群智贡献审阅等功能让您的项目在这里健康、快速的成长
- “互联网即资源库”的全新软件复用模式 成长式软件资源管理系统,实现了分散资源的知识融合、资源的可持续增长和有效复用。
- **一站式过程管理**提供易修Issue、里程碑、通知提醒、标签归档等多样化任务管理工具支持各类开发任务的发布、指派与跟踪同时提供在线Wiki文档、组织多粒度管理等功能为您搭建一站式的项目过程管理环境让您的团队协作更高效、过程更透明
## 部署
- **高效流水线运维**融合DevOps思想提供轻量级的工作流引擎Engine打通编码、测试、构建、部署等开发运维环节支持自定义配置、代码静态扫描、构建自动触发、容器镜像托管等功能同时支持接入第三方运维工具让您的代码更加快速、可靠地形成高质量的产品
- **多层次代码分析**提供软件软代码和芯片RTL代码的溯源分析、文件级和组件级许可证识别及风险分析、输入性开源漏洞检测和加固建议支持分析结果的多层次可视化展示帮助您实施有效开源治理厘清代码引用链发现并消除漏洞感染链为安全合规的开源引用保驾护航
- **多维度用户画像**:实时采集和分析平台中的各类开源资源数据,搭建多维度用户画像评估系统,提供开发活动统计、贡献度日历、用户能力建模、角色与专业定位分析等功能,让您在个人主页展示开发动态与创新能力!
## 第三方组件
### Depends Versions
## 部署流程
### 依赖库
* Ruby 2.4.5
@ -23,22 +36,19 @@ Trustie (确实)是一个以大众化协同开发、开放式资源共享、
* imagemagick
### Steps
### 步骤
#### 1. 克隆稳定版本
1克隆稳定版本
```
git clone -b standalone https://git.trustie.net/jasder/forgeplus.git
```
#### 2. 安装依赖包
2安装依赖包
```bash
cd forgeplus && bundle install
```
#### 3. 配置初始化文件
进入项目根目录执行一下命令:
3配置初始化文件进入项目根目录执行以下命令
```bash
cp config/configuration.yml.example config/configuration.yml
cp config/database.yml.example config/database.yml
@ -46,11 +56,7 @@ touch config/redis.yml
touch config/elasticsearch.yml
```
#### 4. 配置数据库
数据库配置信息请查看/config/database.yml文件
项目默认采用mysql数据库, 如需更改,请自行修改配置信息,
默认配置如下:
4配置数据库数据库配置信息请查看/config/database.yml文件项目默认采用mysql数据库, 如需更改,请自行修改配置信息,默认配置如下
```bash
default: &default
adapter: mysql2
@ -60,14 +66,13 @@ default: &default
password: 123456
```
#### 5. 配置gitea服务(可选)
**如需要部署自己的gitea平台请参考gitea官方平台https://docs.gitea.io/zh-cn/install-from-binary/**
5配置gitea服务(可选)如需要部署自己的gitea平台请参考[gitea官方平台文档](https://docs.gitea.io/zh-cn/install-from-binary/)。因目前gitea平台api受限暂时推荐从forge平台获取[gitea部署文件](https://forgeplus.trustie.net/projects/Trustie/gitea-binary)进行部署
**因目前gitea平台api受限暂时推荐从forge平台获取gitea部署文件进行部署https://forgeplus.trustie.net/projects/Trustie/gitea-binary**
**配置gitea服务步骤**
1. 部署gitea服务并注册root账户
2. 修改forge平台的 config/configuration.yml中的gitea服务指向地址
- 配置gitea服务步骤
-- 部署gitea服务并注册root账户
-- 修改forge平台的 config/configuration.yml中的gitea服务指向地址
```ruby
gitea:
@ -77,10 +82,9 @@ gitea:
base_url: '/api/v1'
```
#### 6. 安装redis环境
**请自行搜索各平台如何安装部署redis环境**
6安装redis环境请自行搜索各平台如何安装部署redis环境
#### 7. 安装imagemagick插件
7安装imagemagick插件
- Mac OS X
```bash
brew install imagemagick ghostscript
@ -91,88 +95,95 @@ gitea:
sudo apt-get install -y imagemagick
```
#### 8. 创建数据库
**开发环境为development 生成环境为production**
8创建数据库开发环境为development 生成环境为production
```bash
rails db:create RAILS_ENV=development
```
#### 9. 导入数据表结构
9导入数据表结构
```bash
bundle exec rake sync_table_structure:import_csv
```
#### 10. 执行migrate迁移文件
**开发环境为development 生成环境为production**
10执行migrate迁移文件开发环境为development 生成环境为production
```bash
rails db:migrate RAILS_ENV=development
```
#### 11. clone前端代码
**将前端代码克隆到public/react目录下目录结构应该是: public/react/build**
11clone前端代码将前端代码克隆到public/react目录下目录结构应该是: public/react/build
```bash
git clone -b standalone https://git.trustie.net/jasder/build.git
```
#### 12. 启动redis(此处已mac系统为例)
12启动redis(此处以macOS系统为例)
```bash
redis-server&
```
#### 13. 启动sidekiq
**开发环境为development 生成环境为production**
13启动sidekiq开发环境为development 生成环境为production
```bash
bundle exec sidekiq -C config/sidekiq.yml -e production -d
```
#### 14. 启动rails服务
14启动rails服务
```bash
rails s
```
#### 15. 浏览器访问
在浏览器中输入如下地址访问:
15浏览器访问在浏览器中输入如下地址访问
```bash
http://localhost:3000/
```
#### 16. 其他说明
通过页面注册都第一个用户为平台管理员用户
16其他说明通过页面注册以第一个用户为平台管理员用户
## 页面展示
- 代码库
![](docs/figs/code.png?raw=true)
- 项目列表
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/project_list.png?raw=true" width=50% />
</center>
- 代码仓库
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/repo.png?raw=true" width=50% />
</center>
- 任务管理
![](docs/figs/issue_manage.png?raw=true)
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/issues.png?raw=true" width=50% />
</center>
- 合并请求
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/PR.png?raw=true" width=50% />
</center>
- 引擎配置
<center>
<img src="https://code.gitlink.org.cn/young/forgeplus/raw/branch/standalone/docs/figs/engine.png?raw=true" width=50% />
</center>
- 任务查看
![](docs/figs/issue_view.png?raw=true)
- 任务指派
![](docs/figs/issue_assign2.png?raw=true)
- 里程碑
![](docs/figs/milestone.png?raw=true)
### API
- [API文档](https://forgeplus.trustie.net/docs/api)
- [API](showdoc.com.cn)
账号forgeplus@admin.com 密码forge123
## 贡献代码
我们期待您向GitLink提交贡献在您贡献时请遵循以下流程
1. Fork 项目
2. 创建本地分支(git checkout -b my-new-feature)
3. 提交更改 (git commit -am 'Add some feature')
4. 推送到分支 (git push origin my-new-feature)
5. 向源项目的 **develop** 分支发起 Pull Request
## License
#### 指导文档
- [API文档](https://www.gitlink.org.cn/docs/api)
- [Git常用命令](https://git-scm.com/)
## 许可证协议

View File

@ -1,371 +1,384 @@
class AccountsController < ApplicationController
include ApplicationHelper
#skip_before_action :check_account, :only => [:logout]
def index
render json: session
end
# 其他平台同步注册的用户
def remote_register
username = params[:username]&.gsub(/\s+/, "")
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
email = params[:email]&.gsub(/\s+/, "")
password = params[:password]
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
ActiveRecord::Base.transaction do
result = autologin_register(username, email, password, platform)
if result[:message].blank?
render_ok({user: result[:user]})
else
render_error(result[:message])
end
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
# 其他平台修改用户的信息,这边同步修改
def remote_update
ActiveRecord::Base.transaction do
user_params = params[:user_params]
user_extension_params = params[:user_extension_params]
u = User.find_by(login: params[:old_user_login])
user_mail = u.try(:mail)
if u.present?
ue = u.user_extension
u.login = user_params["login"] if user_params["login"]
u.mail = user_params["mail"] if user_params["mail"]
u.lastname = user_params["lastname"] if user_params["lastname"]
ue.gender = user_extension_params["gender"]
ue.school_id = user_extension_params["school_id"]
ue.location = user_extension_params["location"]
ue.location_city = user_extension_params["location_city"]
ue.identity = user_extension_params["identity"]
ue.technical_title = user_extension_params["technical_title"]
ue.student_id = user_extension_params["student_id"]
ue.description = user_extension_params["description"]
ue.save!
u.save!
sync_params = {}
if (user_params["mail"] && user_params["mail"] != user_mail)
sync_params = sync_params.merge(email: user_params["mail"])
end
if sync_params.present?
interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params)
if interactor.success?
render_ok
else
render_error(interactor.error)
end
end
end
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
# 其他平台同步登录
def remote_login
@user = User.try_to_login(params[:login], params[:password])
if @user
successful_authentication(@user)
render_ok({user: {id: @user.id, token: @user.gitea_token}})
else
render_error("用户不存在")
end
end
#修改密码
def remote_password
@user = User.find_by(login: params[:login])
return render_error("未找到相关用户!") if @user.blank?
sync_params = {
password: params[:password].to_s,
email: @user.mail
}
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
if interactor.success?
@user.update_attribute(:password, params[:password])
render_ok
else
render_error(interactor.error)
end
end
# 用户注册
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
# params[:login] 邮箱或者手机号
# params[:namespace] 登录名
# params[:code] 验证码
# code_type 1注册手机验证码 8邮箱注册验证码
# 本地forge注册入口需要重新更改逻辑
def register
# type只可能是1或者8
user = nil
begin
Register::Form.new(register_params).validate!
user = Users::RegisterService.call(register_params)
password = register_params[:password].strip
# gitea用户注册, email, username, password
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(user.login, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
if user.save!
UserExtension.create!(user_id: user.id)
successful_authentication(user)
render_ok
end
else
tip_exception(-1, interactor.error)
end
rescue Register::BaseForm::EmailError => e
render_error(-2, e.message)
rescue Register::BaseForm::LoginError => e
render_error(-3, e.message)
rescue Register::BaseForm::PhoneError => e
render_error(-4, e.message)
rescue Register::BaseForm::PasswordFormatError => e
render_error(-5, e.message)
rescue Register::BaseForm::VerifiCodeError => e
render_error(-6, e.message)
rescue Exception => e
Gitea::User::DeleteService.call(user.login) unless user.nil?
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
end
# 用户登录
def login
Users::LoginForm.new(account_params).validate!
@user = User.try_to_login(params[:login], params[:password])
return normal_status(-2, "错误的账号或密码") if @user.blank?
# user is already in local database
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
login_control = LimitForbidControl::UserLogin.new(@user)
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
password_ok = @user.check_password?(params[:password].to_s)
unless password_ok
if login_control.remain_times-1 == 0
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
else
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
end
login_control.increment!
return
end
successful_authentication(@user)
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
# session[:user_id] = @user.id
end
def change_password
@user = User.find_by(login: params[:login])
return render_error("未找到相关用户!") if @user.blank?
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
sync_params = {
password: params[:password].to_s,
email: @user.mail
}
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
if interactor.success?
@user.update_attribute(:password, params[:password])
render_ok
else
render_error(interactor.error)
end
end
# 忘记密码
def reset_password
begin
code = params[:code]
login_type = phone_mail_type(params[:login].strip)
# 获取验证码
if login_type == 1
phone = params[:login]
verifi_code = VerificationCode.where(phone: phone, code: code, code_type: 2).last
user = User.find_by_phone(phone)
else
email = params[:login]
verifi_code = VerificationCode.where(email: email, code: code, code_type: 3).last
user = User.find_by_mail(email) #这里有问题应该是为email,而不是mail 6.13-hs
end
return normal_status(-2, "验证码不正确") if verifi_code.try(:code) != code.strip
return normal_status(-2, "验证码已失效") if !verifi_code&.effective?
return normal_status(-1, "8~16位密码支持字母数字和符号") unless params[:new_password] =~ CustomRegexp::PASSWORD
user.password, user.password_confirmation = params[:new_password], params[:new_password_confirmation]
ActiveRecord::Base.transaction do
user.save!
LimitForbidControl::UserLogin.new(user).clear
end
sucess_status
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
end
def successful_authentication(user)
uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
# Valid user
self.logged_user = user
# generate a key and set cookie if autologin
set_autologin_cookie(user)
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
user.update_column(:last_login_on, Time.now)
session[:"#{default_yun_session}"] = user.id
Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
# 注册完成后有一天的试用申请(先去掉)
# UserDayCertification.create(user_id: user.id, status: 1)
end
def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user, "autologin")
sync_user_token_to_trustie(user.login, token.value)
cookie_options = {
:value => token.value,
:expires => 1.month.from_now,
:path => '/',
:secure => false,
:httponly => true
}
if edu_setting('cookie_domain').present?
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
end
cookies[autologin_cookie_name] = cookie_options
cookies.signed[:user_id] ||= user.id
logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}")
end
def logout
Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}")
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
logout_user
render :json => {status: 1, message: "退出成功!"}
end
# 检验邮箱是否已被注册及邮箱或者手机号是否合法
# 参数type为事件类型 1注册2忘记密码3绑定
def valid_email_and_phone
check_mail_and_phone_valid(params[:login], params[:type])
end
# 发送验证码
# params[:login] 手机号或者邮箱号
# params[:type]为事件通知类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# 发送验证码send_type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9: 验收手机号有效
def get_verification_code
code = %W(0 1 2 3 4 5 6 7 8 9)
value = params[:login]
type = params[:type].strip.to_i
login_type = phone_mail_type(value)
send_type = verify_type(login_type, type)
verification_code = code.sample(6).join
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
tip_exception(501, "请求不合理") if sign != params[:smscode]
logger.info "########### 验证码:#{verification_code}"
logger.info("########get_verification_code: login_type #{login_type} send_type#{send_type}, ")
# 记录验证码
check_verification_code(verification_code, send_type, value)
render_ok
end
# check user's login or email or phone is used
# params[:value] 手机号或者邮箱号或者登录名
# params[:type] 为事件类型 1登录名(login) 2email(邮箱) 3phone(手机号)
def check
Register::CheckColumnsForm.new(check_params).validate!
render_ok
end
private
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
# login_type 1手机类型 2邮箱类型
def verify_type login_type, type
case type
when 1
login_type == 1 ? 1 : 8
when 2
login_type == 1 ? 2 : 3
when 3
login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
when 4
login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
when 5
login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
end
end
def generate_login(login)
type = phone_mail_type(login.strip)
if type == 1
uid_logger("start register by phone: type is #{type}")
pre = 'p'
email = nil
phone = login
else
uid_logger("start register by email: type is #{type}")
pre = 'm'
email = login
phone = nil
end
code = generate_identifier User, 8, pre
{ login: pre + code, email: email, phone: phone }
end
def user_params
params.require(:user).permit(:login, :email, :phone)
end
def account_params
params.require(:account).permit(:login, :password)
end
def check_params
params.permit(:type, :value)
end
def register_params
params.permit(:login, :namespace, :password, :code)
end
end
class AccountsController < ApplicationController
include ApplicationHelper
def index
render json: session
end
# 其他平台同步注册的用户
def remote_register
Register::RemoteForm.new(remote_register_params).validate!
username = params[:username]&.gsub(/\s+/, "")
tip_exception("无法使用以下关键词:#{username},请重新命名") if ReversedKeyword.check_exists?(username)
email = params[:email]&.gsub(/\s+/, "")
password = params[:password]
platform = (params[:platform] || 'forge')&.gsub(/\s+/, "")
ActiveRecord::Base.transaction do
result = autologin_register(username, email, password, platform)
if result[:message].blank?
render_ok({user: result[:user]})
else
render_error(result[:message])
end
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
# 其他平台修改用户的信息,这边同步修改
def remote_update
ActiveRecord::Base.transaction do
user_params = params[:user_params]
user_extension_params = params[:user_extension_params]
u = User.find_by(login: params[:old_user_login])
user_mail = u.try(:mail)
if u.present?
ue = u.user_extension
u.login = user_params["login"] if user_params["login"]
u.mail = user_params["mail"] if user_params["mail"]
u.lastname = user_params["lastname"] if user_params["lastname"]
ue.gender = user_extension_params["gender"]
ue.school_id = user_extension_params["school_id"]
ue.location = user_extension_params["location"]
ue.location_city = user_extension_params["location_city"]
ue.identity = user_extension_params["identity"]
ue.technical_title = user_extension_params["technical_title"]
ue.student_id = user_extension_params["student_id"]
ue.description = user_extension_params["description"]
ue.save!
u.save!
sync_params = {}
if (user_params["mail"] && user_params["mail"] != user_mail)
sync_params = sync_params.merge(email: user_params["mail"])
end
if sync_params.present?
interactor = Gitea::User::UpdateInteractor.call(u.login, sync_params)
if interactor.success?
render_ok
else
render_error(interactor.error)
end
end
end
end
rescue Exception => e
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
# 其他平台同步登录
def remote_login
@user = User.try_to_login(params[:login], params[:password])
if @user
successful_authentication(@user)
render_ok({user: {id: @user.id, token: @user.gitea_token}})
else
render_error("用户不存在")
end
end
#修改密码
def remote_password
@user = User.find_by(login: params[:login])
return render_error("未找到相关用户!") if @user.blank?
sync_params = {
password: params[:password].to_s,
email: @user.mail
}
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
if interactor.success?
@user.update_attribute(:password, params[:password])
render_ok
else
render_error(interactor.error)
end
end
# 用户注册
# 注意:用户注册需要兼顾本地版,本地版是不需要验证码及激活码以及使用授权的,注册完成即可使用
# params[:login] 邮箱或者手机号
# params[:namespace] 登录名
# params[:code] 验证码
# code_type 1注册手机验证码 8邮箱注册验证码
# 本地forge注册入口需要重新更改逻辑
def register
# type只可能是1或者8
user = nil
begin
Register::Form.new(register_params).validate!
user = Users::RegisterService.call(register_params)
password = register_params[:password].strip
# gitea用户注册, email, username, password
interactor = Gitea::RegisterInteractor.call({username: user.login, email: user.mail, password: password})
if interactor.success?
gitea_user = interactor.result
result = Gitea::User::GenerateTokenService.call(user.login, password)
user.gitea_token = result['sha1']
user.gitea_uid = gitea_user[:body]['id']
if user.save!
UserExtension.create!(user_id: user.id)
successful_authentication(user)
render_ok
end
else
tip_exception(-1, interactor.error)
end
rescue Register::BaseForm::EmailError => e
render_result(-2, e.message)
rescue Register::BaseForm::LoginError => e
render_result(-3, e.message)
rescue Register::BaseForm::PhoneError => e
render_result(-4, e.message)
rescue Register::BaseForm::PasswordFormatError => e
render_result(-5, e.message)
rescue Register::BaseForm::PasswordConfirmationError => e
render_result(-7, e.message)
rescue Register::BaseForm::VerifiCodeError => e
render_result(-6, e.message)
rescue Exception => e
Gitea::User::DeleteService.call(user.login) unless user.nil?
uid_logger_error(e.message)
tip_exception(-1, e.message)
end
end
# 用户登录
def login
Users::LoginForm.new(login_params).validate!
@user = User.try_to_login(params[:login], params[:password])
return normal_status(-2, "错误的账号或密码") if @user.blank?
# user is already in local database
return normal_status(-2, "违反平台使用规范,账号已被锁定") if @user.locked?
login_control = LimitForbidControl::UserLogin.new(@user)
return normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码") if login_control.forbid?
password_ok = @user.check_password?(params[:password].to_s)
unless password_ok
if login_control.remain_times-1 == 0
normal_status(-2, "登录密码出错已达上限,账号已被锁定, 请#{login_control.forbid_expires/60}分钟后重新登录或找回密码")
else
normal_status(-2, "你已经输错密码#{login_control.error_times+1}次,还剩余#{login_control.remain_times-1}次机会")
end
login_control.increment!
return
end
successful_authentication(@user)
sync_pwd_to_gitea!(@user, {password: params[:password].to_s}) # TODO用户密码未同步
# session[:user_id] = @user.id
end
def change_password
@user = User.find_by(login: params[:login])
return render_error("未找到相关用户!") if @user.blank?
return render_error("旧密码不正确") unless @user.check_password?(params[:old_password])
sync_params = {
password: params[:password].to_s,
email: @user.mail
}
interactor = Gitea::User::UpdateInteractor.call(@user.login, sync_params)
if interactor.success?
@user.update_attribute(:password, params[:password])
render_ok
else
render_error(interactor.error)
end
end
# 忘记密码
def reset_password
begin
Accounts::ResetPasswordForm.new(reset_password_params).validate!
user = find_user
return render_error('未找到相关账号') if user.blank?
user = Accounts::ResetPasswordService.call(user, reset_password_params)
LimitForbidControl::UserLogin.new(user).clear if user.save!
render_ok
rescue Register::BaseForm::EmailError => e
render_result(-2, e.message)
rescue Register::BaseForm::PhoneError => e
render_result(-4, e.message)
rescue Register::BaseForm::PasswordFormatError => e
render_result(-5, e.message)
rescue Register::BaseForm::PasswordConfirmationError => e
render_result(-7, e.message)
rescue Register::BaseForm::VerifiCodeError => e
render_result(-6, e.message)
rescue ActiveRecord::Rollback => e
render_result(-1, "服务器异常")
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)
end
end
def successful_authentication(user)
uid_logger("Successful authentication start: '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}")
# Valid user
self.logged_user = user
# generate a key and set cookie if autologin
set_autologin_cookie(user)
UserAction.create(:action_id => user.try(:id), :action_type => "Login", :user_id => user.try(:id), :ip => request.remote_ip)
user.update_column(:last_login_on, Time.now)
session[:"#{default_yun_session}"] = user.id
Rails.logger.info("#########_____session_default_yun_session__________###############{default_yun_session}")
# 注册完成后有一天的试用申请(先去掉)
# UserDayCertification.create(user_id: user.id, status: 1)
end
def set_autologin_cookie(user)
token = Token.get_or_create_permanent_login_token(user, "autologin")
# sync_user_token_to_trustie(user.login, token.value)
cookie_options = {
:value => token.value,
:expires => 1.month.from_now,
:path => '/',
:secure => false,
:httponly => true
}
if edu_setting('cookie_domain').present?
cookie_options = cookie_options.merge(domain: edu_setting('cookie_domain'))
end
cookies[autologin_cookie_name] = cookie_options
cookies.signed[:user_id] ||= user.id
logger.info("cookies is #{cookies} ======> #{cookies.signed[:user_id]} =====> #{cookies[autologin_cookie_name]}")
end
def logout
Rails.logger.info("########___logout_current_user____________########{current_user.try(:id)}")
UserAction.create(action_id: User.current.id, action_type: "Logout", user_id: User.current.id, :ip => request.remote_ip)
logout_user
render :json => {status: 1, message: "退出成功!"}
end
# 检验邮箱是否已被注册及邮箱或者手机号是否合法
# 参数type为事件类型 1注册2忘记密码3绑定
def valid_email_and_phone
check_mail_and_phone_valid(params[:login], params[:type])
end
# 发送验证码
# params[:login] 手机号或者邮箱号
# params[:type]为事件通知类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验收手机号有效 # 如果有新的继续后面加
# 发送验证码send_type 1注册手机验证码 2找回密码手机验证码 3找回密码邮箱验证码 4绑定手机 5绑定邮箱
# 6手机验证码登录 7邮箱验证码登录 8邮箱注册验证码 9: 验收手机号有效
def get_verification_code
code = %W(0 1 2 3 4 5 6 7 8 9)
value = params[:login]
type = params[:type].strip.to_i
login_type = phone_mail_type(value)
send_type = verify_type(login_type, type)
verification_code = code.sample(6).join
sign = Digest::MD5.hexdigest("#{OPENKEY}#{value}")
tip_exception(501, "请求不合理") if sign != params[:smscode]
logger.info "########### 验证码:#{verification_code}"
logger.info("########get_verification_code: login_type #{login_type} send_type#{send_type}, ")
# 记录验证码
check_verification_code(verification_code, send_type, value)
render_ok
end
# check user's login or email or phone is used
# params[:value] 手机号或者邮箱号或者登录名
# params[:type] 为事件类型 1登录名(login) 2email(邮箱) 3phone(手机号)
def check
Register::CheckColumnsForm.new(check_params).validate!
render_ok
end
private
# type 事件类型 1用户注册 2忘记密码 3: 绑定手机 4: 绑定邮箱, 5: 验证手机号是否有效 # 如果有新的继续后面加
# login_type 1手机类型 2邮箱类型
def verify_type login_type, type
case type
when 1
login_type == 1 ? 1 : 8
when 2
login_type == 1 ? 2 : 3
when 3
login_type == 1 ? 4 : tip_exception('请填写正确的手机号')
when 4
login_type == 1 ? tip_exception('请填写正确的邮箱') : 5
when 5
login_type == 1 ? 9 : tip_exception('请填写正确的手机号')
end
end
def generate_login(login)
type = phone_mail_type(login.strip)
if type == 1
uid_logger("start register by phone: type is #{type}")
pre = 'p'
email = nil
phone = login
else
uid_logger("start register by email: type is #{type}")
pre = 'm'
email = login
phone = nil
end
code = generate_identifier User, 8, pre
{ login: pre + code, email: email, phone: phone }
end
def user_params
params.require(:user).permit(:login, :email, :phone)
end
def login_params
params.require(:account).permit(:login, :password)
end
def check_params
params.permit(:type, :value)
end
def register_params
params.permit(:login, :namespace, :password, :password_confirmation, :code)
end
def reset_password_params
params.permit(:login, :password, :password_confirmation, :code)
end
def find_user
phone_or_mail = strip(reset_password_params[:login])
User.where("phone = :search OR mail = :search", search: phone_or_mail).last
end
def remote_register_params
params.permit(:username, :email, :password, :platform)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::ActivityForumsController < Admins::Topic::BaseController
before_action :find_activity_forum, only: [:edit, :update, :destroy]
def index
q = ::Topic::ActivityForum.ransack(title_cont: params[:search])
activity_forums = q.result(distinct: true)
@activity_forums = paginate(activity_forums)
end
def new
@activity_forum = ::Topic::ActivityForum.new
end
def create
@activity_forum = ::Topic::ActivityForum.new(activity_forum_params)
if @activity_forum.save
redirect_to admins_topic_activity_forums_path
flash[:success] = "新增平台动态成功"
else
redirect_to admins_topic_activity_forums_path
flash[:danger] = "新增平台动态失败"
end
end
def edit
end
def update
@activity_forum.attributes = activity_forum_params
if @activity_forum.save
redirect_to admins_topic_activity_forums_path
flash[:success] = "更新平台动态成功"
else
redirect_to admins_topic_activity_forums_path
flash[:danger] = "更新平台动态失败"
end
end
def destroy
if @activity_forum.destroy
redirect_to admins_topic_activity_forums_path
flash[:success] = "删除平台动态成功"
else
redirect_to admins_topic_activity_forums_path
flash[:danger] = "删除平台动态失败"
end
end
private
def find_activity_forum
@activity_forum = ::Topic::ActivityForum.find_by_id(params[:id])
end
def activity_forum_params
params.require(:topic_activity_forum).permit(:title, :uuid, :url, :order_index)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::BannersController < Admins::Topic::BaseController
before_action :find_banner, only: [:edit, :update, :destroy]
def index
@banners = paginate(::Topic::Banner)
end
def new
@banner = ::Topic::Banner.new
end
def create
@banner = ::Topic::Banner.new(banner_params)
if @banner.save
save_image_file(params[:image], @banner)
redirect_to admins_topic_banners_path
flash[:success] = "新增banner成功"
else
redirect_to admins_topic_banners_path
flash[:danger] = "新增banner失败"
end
end
def edit
end
def update
@banner.attributes = banner_params
if @banner.save
save_image_file(params[:image], @banner)
redirect_to admins_topic_banners_path
flash[:success] = "更新banner成功"
else
redirect_to admins_topic_banners_path
flash[:danger] = "更新banner失败"
end
end
def destroy
if @banner.destroy
redirect_to admins_topic_banners_path
flash[:success] = "删除banner成功"
else
redirect_to admins_topic_banners_path
flash[:danger] = "删除banner失败"
end
end
private
def find_banner
@banner = ::Topic::Banner.find_by_id(params[:id])
end
def banner_params
params.require(:topic_banner).permit(:title, :order_index)
end
end

View File

@ -0,0 +1,11 @@
class Admins::Topic::BaseController < Admins::BaseController
protected
def save_image_file(file, topic)
return unless file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
file_path = Util::FileManage.source_disk_filename(topic, 'image')
File.delete(file_path) if File.exist?(file_path) # 删除之前的文件
Util.write_file(file, file_path)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::CardsController < Admins::Topic::BaseController
before_action :find_card, only: [:edit, :update, :destroy]
def index
q = ::Topic::Card.ransack(title_cont: params[:search])
cards = q.result(distinct: true)
@cards = paginate(cards)
end
def new
@card = ::Topic::Card.new
end
def create
@card = ::Topic::Card.new(card_params)
if @card.save
redirect_to admins_topic_cards_path
flash[:success] = "新增合作单位成功"
else
redirect_to admins_topic_cards_path
flash[:danger] = "新增合作单位失败"
end
end
def edit
end
def update
@card.attributes = card_params
if @card.save
redirect_to admins_topic_cards_path
flash[:success] = "更新合作单位成功"
else
redirect_to admins_topic_cards_path
flash[:danger] = "更新合作单位失败"
end
end
def destroy
if @card.destroy
redirect_to admins_topic_cards_path
flash[:success] = "删除合作单位成功"
else
redirect_to admins_topic_cards_path
flash[:danger] = "删除合作单位失败"
end
end
private
def find_card
@card = ::Topic::Card.find_by_id(params[:id])
end
def card_params
params.require(:topic_card).permit(:title, :url, :order_index)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::CooperatorsController < Admins::Topic::BaseController
before_action :find_cooperator, only: [:edit, :update, :destroy]
def index
@cooperators = paginate(::Topic::Cooperator)
end
def new
@cooperator = ::Topic::Cooperator.new
end
def create
@cooperator = ::Topic::Cooperator.new(cooperator_params)
if @cooperator.save
save_image_file(params[:image], @cooperator)
redirect_to admins_topic_cooperators_path
flash[:success] = "新增合作单位成功"
else
redirect_to admins_topic_cooperators_path
flash[:danger] = "新增合作单位失败"
end
end
def edit
end
def update
@cooperator.attributes = cooperator_params
if @cooperator.save
save_image_file(params[:image], @cooperator)
redirect_to admins_topic_cooperators_path
flash[:success] = "更新合作单位成功"
else
redirect_to admins_topic_cooperators_path
flash[:danger] = "更新合作单位失败"
end
end
def destroy
if @cooperator.destroy
redirect_to admins_topic_cooperators_path
flash[:success] = "删除合作单位成功"
else
redirect_to admins_topic_cooperators_path
flash[:danger] = "删除合作单位失败"
end
end
private
def find_cooperator
@cooperator = ::Topic::Cooperator.find_by_id(params[:id])
end
def cooperator_params
params.require(:topic_cooperator).permit(:title, :url, :order_index)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::ExcellentProjectsController < Admins::Topic::BaseController
before_action :find_excellent_project, only: [:edit, :update, :destroy]
def index
q = ::Topic::ExcellentProject.ransack(title_cont: params[:search])
excellent_projects = q.result(distinct: true)
@excellent_projects = paginate(excellent_projects)
end
def new
@excellent_project = ::Topic::ExcellentProject.new
end
def create
@excellent_project = ::Topic::ExcellentProject.new(excellent_project_params)
if @excellent_project.save
redirect_to admins_topic_excellent_projects_path
flash[:success] = "新增优秀仓库成功"
else
redirect_to admins_topic_excellent_projects_path
flash[:danger] = "新增优秀仓库失败"
end
end
def edit
end
def update
@excellent_project.attributes = excellent_project_params
if @excellent_project.save
redirect_to admins_topic_excellent_projects_path
flash[:success] = "更新优秀仓库成功"
else
redirect_to admins_topic_excellent_projects_path
flash[:danger] = "更新优秀仓库失败"
end
end
def destroy
if @excellent_project.destroy
redirect_to admins_topic_excellent_projects_path
flash[:success] = "删除优秀仓库成功"
else
redirect_to admins_topic_excellent_projects_path
flash[:danger] = "删除优秀仓库失败"
end
end
private
def find_excellent_project
@excellent_project = ::Topic::ExcellentProject.find_by_id(params[:id])
end
def excellent_project_params
params.require(:topic_excellent_project).permit(:title, :uuid, :url, :order_index)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::ExperienceForumsController < Admins::Topic::BaseController
before_action :find_experience_forum, only: [:edit, :update, :destroy]
def index
q = ::Topic::ExperienceForum.ransack(title_cont: params[:search])
experience_forums = q.result(distinct: true)
@experience_forums = paginate(experience_forums)
end
def new
@experience_forum = ::Topic::ExperienceForum.new
end
def create
@experience_forum = ::Topic::ExperienceForum.new(experience_forum_params)
if @experience_forum.save
redirect_to admins_topic_experience_forums_path
flash[:success] = "新增经验分享成功"
else
redirect_to admins_topic_experience_forums_path
flash[:danger] = "新增经验分享失败"
end
end
def edit
end
def update
@experience_forum.attributes = experience_forum_params
if @experience_forum.save
redirect_to admins_topic_experience_forums_path
flash[:success] = "更新经验分享成功"
else
redirect_to admins_topic_experience_forums_path
flash[:danger] = "更新经验分享失败"
end
end
def destroy
if @experience_forum.destroy
redirect_to admins_topic_experience_forums_path
flash[:success] = "删除经验分享成功"
else
redirect_to admins_topic_experience_forums_path
flash[:danger] = "删除经验分享失败"
end
end
private
def find_experience_forum
@experience_forum = ::Topic::ExperienceForum.find_by_id(params[:id])
end
def experience_forum_params
params.require(:topic_experience_forum).permit(:title, :uuid, :url, :order_index)
end
end

View File

@ -0,0 +1,57 @@
class Admins::Topic::PinnedForumsController < Admins::Topic::BaseController
before_action :find_pinned_forum, only: [:edit, :update, :destroy]
def index
q = ::Topic::PinnedForum.ransack(title_cont: params[:search])
pinned_forums = q.result(distinct: true)
@pinned_forums = paginate(pinned_forums)
end
def new
@pinned_forum = ::Topic::PinnedForum.new
end
def create
@pinned_forum = ::Topic::PinnedForum.new(pinned_forum_params)
if @pinned_forum.save
redirect_to admins_topic_pinned_forums_path
flash[:success] = "新增精选文章成功"
else
redirect_to admins_topic_pinned_forums_path
flash[:danger] = "新增精选文章失败"
end
end
def edit
end
def update
@pinned_forum.attributes = pinned_forum_params
if @pinned_forum.save
redirect_to admins_topic_pinned_forums_path
flash[:success] = "更新精选文章成功"
else
redirect_to admins_topic_pinned_forums_path
flash[:danger] = "更新精选文章失败"
end
end
def destroy
if @pinned_forum.destroy
redirect_to admins_topic_pinned_forums_path
flash[:success] = "删除精选文章成功"
else
redirect_to admins_topic_pinned_forums_path
flash[:danger] = "删除精选文章失败"
end
end
private
def find_pinned_forum
@pinned_forum = ::Topic::PinnedForum.find_by_id(params[:id])
end
def pinned_forum_params
params.require(:topic_pinned_forum).permit(:title, :uuid, :url, :order_index)
end
end

View File

@ -26,7 +26,8 @@ class ApplicationController < ActionController::Base
end
DCODES = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z)
OPENKEY = "79e33abd4b6588941ab7622aed1e67e8"
OPENKEY = Rails.application.config_for(:configuration)['sign_key'] || "79e33abd4b6588941ab7622aed1e67e8"
helper_method :current_user, :base_url
@ -264,7 +265,6 @@ class ApplicationController < ActionController::Base
User.current = user
end
end
# if !User.current.logged? && Rails.env.development?
# User.current = User.find 1
# end
@ -272,18 +272,18 @@ class ApplicationController < ActionController::Base
# 测试版前端需求
logger.info("subdomain:#{request.subdomain}")
# if request.subdomain != "www"
# if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
# User.current = User.find 81403
# elsif params[:debug] == 'student'
# User.current = User.find 8686
# elsif params[:debug] == 'admin'
# logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
# user = User.find 36480
# User.current = user
# cookies.signed[:user_id] = user.id
# end
# end
if request.subdomain != "www"
if params[:debug] == 'teacher' #todo 为了测试,记得讲debug删除
User.current = User.find 81403
elsif params[:debug] == 'student'
User.current = User.find 8686
elsif params[:debug] == 'admin'
logger.info "@@@@@@@@@@@@@@@@@@@@@@ debug mode....."
user = User.find 36480
User.current = user
cookies.signed[:user_id] = user.id
end
end
# User.current = User.find 81403
end
@ -336,11 +336,6 @@ class ApplicationController < ActionController::Base
@message = message
end
# 实训等对应的仓库地址
def repo_ip_url(repo_path)
"#{edu_setting('git_address_ip')}/#{repo_path}"
end
def repo_url(repo_path)
"#{edu_setting('git_address_domain')}/#{repo_path}"
end
@ -609,7 +604,7 @@ class ApplicationController < ActionController::Base
def kaminari_paginate(relation)
limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
relation.page(page).per(limit)
@ -617,7 +612,7 @@ class ApplicationController < ActionController::Base
def kaminari_array_paginate(relation)
limit = params[:limit] || params[:per_page]
limit = (limit.to_i.zero? || limit.to_i > 15) ? 15 : limit.to_i
limit = (limit.to_i.zero? || limit.to_i > 20) ? 20 : limit.to_i
page = params[:page].to_i.zero? ? 1 : params[:page].to_i
Kaminari.paginate_array(relation).page(page).per(limit)
@ -709,14 +704,20 @@ class ApplicationController < ActionController::Base
Rails.application.config_for(:configuration)['platform_url'] || request.base_url
end
def image_type?(str)
default_type = %w(png jpg gif tif psd svg bmp webp jpeg ico psd)
default_type.include?(str&.downcase)
end
def convert_image!
@image = params[:image]
@image = @image.nil? && params[:user].present? ? params[:user][:image] : @image
return unless @image.present?
max_size = EduSetting.get('upload_avatar_max_size') || 2 * 1024 * 1024 # 2M
if @image.class == ActionDispatch::Http::UploadedFile
render_error('请上传文件') if @image.size.zero?
render_error('文件大小超过限制') if @image.size > max_size.to_i
return render_error('请上传文件') if @image.size.zero?
return render_error('文件大小超过限制') if @image.size > max_size.to_i
return render_error('头像格式不正确!') unless image_type?(File.extname(@image.original_filename.to_s)[1..-1])
else
image = @image.to_s.strip
return render_error('请上传正确的图片') if image.blank?
@ -742,37 +743,10 @@ class ApplicationController < ActionController::Base
render json: exception.tip_json
end
def render_parameter_missing
render json: { status: -1, message: '参数缺失' }
end
def set_export_cookies
cookies[:fileDownload] = true
end
# 149课程的评审用户数据创建包含创建课堂学生
def open_class_user
user = User.find_by(login: "OpenClassUser")
unless user
ActiveRecord::Base.transaction do
user_params = {status: 1, login: "OpenClassUser", lastname: "开放课程",
nickname: "开放课程", professional_certification: 1, certification: 1, grade: 0,
password: "12345678", phone: "11122223333", profile_completed: 1}
user = User.create!(user_params)
UserExtension.create!(user_id: user.id, gender: 0, school_id: 3396, :identity => 1, :student_id => "openclassuser") # 3396
subject = Subject.find_by(id: 149)
if subject
subject.courses.each do |course|
CourseMember.create!(course_id: course.id, role: 3, user_id: user.id) if !course.course_members.exists?(user_id: user.id)
end
end
end
end
user
end
# 记录热门搜索关键字
def record_search_keyword
keyword = params[:keyword].to_s.strip

View File

@ -0,0 +1,138 @@
#coding=utf-8
class ClaimsController < ApplicationController
# skip_before_action :verify_authenticity_token
protect_from_forgery with: :null_session
before_action :require_login, except: [:index]
before_action :set_issue
def index
@user_claimed = 0
@claims = @issue.claims.claim_includes.order("created_at desc")
@claims.each do |claim|
if claim.user_id == current_user.id
@user_claimed = 1
break
end
end
render file: 'app/views/claims/list.json.jbuilder'
end
def create
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
if @claim.present?
return normal_status(-1,"您已经声明过该易修")
end
ActiveRecord::Base.transaction do
@claim = Claim.new(parse_issue_params(params))
if @claim.save
@claims = @issue.claims.claim_includes.order("created_at desc")
@user_claimed = 1
journal_params = {
journalized_id: params[:issue_id],
journalized_type: "Issue",
user_id: current_user.id ,
notes: "新建声明: #{params[:claim_note]}",
}
journal = Journal.new(journal_params)
if journal.save
render file: 'app/views/claims/list.json.jbuilder'
else
normal_status(-1,"新建声明关联评论操作失败")
end
else
normal_status(-1,"新建声明操作失败")
end
end
end
def update
@claim = Claim.find_by_id(params[:claim_id])
if @claim.blank?
return normal_status(-1,"易修不存在")
end
if @claim.user_id != current_user.id
return normal_status(-1,"你不能更新别人的声明")
end
ActiveRecord::Base.transaction do
if @claim.update_attribute(:note,params[:claim_note])
@claims = @issue.claims.claim_includes.order("created_at desc")
@user_claimed = 1
journal_params = {
journalized_id: params[:issue_id],
journalized_type: "Issue",
user_id: current_user.id ,
notes: "更新声明: #{params[:claim_note]}",
}
journal = Journal.new(journal_params)
if journal.save
render file: 'app/views/claims/list.json.jbuilder'
else
normal_status(-1,"新建声明关联评论操作失败")
end
else
normal_status(-1,"声明更新操作失败")
end
end
end
def destroy
@claim = Claim.find_by_sql(["select id from claims where issue_id=? and user_id=?",params[:issue_id], current_user.id])
if @claim.blank?
normal_status(-1,"您未曾声明过该易修")
else
@claim = @claim[0]
# 判断current user是否是claimer
ActiveRecord::Base.transaction do
if @claim.destroy
@claims = @issue.claims.claim_includes.order("created_at desc")
@user_claimed = 0
journal_params = {
journalized_id: params[:issue_id],
journalized_type: "Issue",
user_id: current_user.id ,
notes: "取消声明",
}
journal = Journal.new(journal_params)
if journal.save
render file: 'app/views/claims/list.json.jbuilder'
else
normal_status(-1,"新建声明关联评论操作失败")
end
else
normal_status(-1,"取消声明操作失败")
end
end
end
end
private
def parse_issue_params(params)
{
issue_id: params[:issue_id],
user_id: current_user.id,
note: params[:claim_note],
}
end
def set_issue
@issue = Issue.find_by_id(params[:issue_id])
unless @issue.present?
normal_status(-1, "易修不存在")
end
end
end

View File

@ -42,12 +42,14 @@ class CompareController < ApplicationController
end
def load_compare_params
@base = Addressable::URI.unescape(params[:base])
@head = params[:head].include?('json') ? params[:head]&.split('.json')[0] : params[:head]
# @base = Addressable::URI.unescape(params[:base])
@base = params[:base].include?(":") ? Addressable::URI.unescape(params[:base].split(":")[0]) + ':' + Base64.decode64(params[:base].split(":")[1]) : Base64.decode64(params[:base])
@head = params[:head].include?('.json') ? params[:head][0..-6] : params[:head]
# @head = Addressable::URI.unescape(@head)
@head = @head.include?(":") ? Addressable::URI.unescape(@head.split(":")[0]) + ':' + Base64.decode64(@head.split(":")[1]) : Base64.decode64(@head)
end
def gitea_compare(base, head)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, base, head, current_user.gitea_token)
Gitea::Repository::Commits::CompareService.call(@owner.login, @project.identifier, CGI.escape(base), CGI.escape(head), current_user.gitea_token)
end
end

View File

@ -1,13 +1,17 @@
module RegisterHelper
extend ActiveSupport::Concern
def autologin_register(username, email, password, platform= 'forge')
def autologin_register(username, email, password, platform= 'forge', need_edit_info = false)
result = {message: nil, user: nil}
user = User.new(admin: false, login: username, mail: email, type: "User")
user.password = password
user.platform = platform
user.activate
if need_edit_info
user.need_edit_info
else
user.activate
end
return unless user.valid?
@ -27,4 +31,31 @@ module RegisterHelper
result
end
def autosync_register_trustie(username, password, email, lastname="")
config = Rails.application.config_for(:configuration).symbolize_keys!
api_host = config[:sync_url]
return if api_host.blank?
url = "#{api_host}/api/v1/users/common"
sync_json = {
"mail": email,
"password": password,
"login": username,
"lastname": lastname
}.compact
uri = URI.parse(url)
if api_host
http = Net::HTTP.new(uri.hostname, uri.port)
if api_host.include?("https://")
http.use_ssl = true
end
http.send_request('POST', uri.path, sync_json.to_json, {'Content-Type' => 'application/json'})
end
end
end

View File

@ -3,8 +3,8 @@ module RenderHelper
render json: { status: 0, message: 'success' }.merge(data)
end
def render_error(status = -1, message = '')
render json: { status: status, message: message }
def render_error(message = '')
render json: { status: -1, message: message }
end
def render_not_acceptable(message = '请求已拒绝')
@ -28,4 +28,8 @@ module RenderHelper
def render_result(status=1, message='success')
render json: { status: status, message: message }
end
def render_parameter_missing
render json: { status: -1, message: '参数缺失' }
end
end

View File

@ -13,7 +13,7 @@ class ForksController < ApplicationController
if current_user&.id == @project.user_id
render_result(-1, "自己不能fork自己的项目")
elsif Project.exists?(user_id: current_user.id, identifier: @project.identifier)
render_result(-1, "fork失败你已拥有了这个项目")
render_result(0, "fork失败你已拥有了这个项目")
end
# return if current_user != @project.owner
# render_result(-1, "自己不能fork自己的项目")

View File

@ -2,7 +2,7 @@ class IssueTagsController < ApplicationController
before_action :require_login, except: [:index]
before_action :load_repository
before_action :set_user
before_action :check_issue_permission, except: :index
before_action :check_issue_tags_permission
before_action :set_issue_tag, only: [:edit, :update, :destroy]
@ -17,7 +17,7 @@ class IssueTagsController < ApplicationController
def create
title = params[:name].to_s.strip.first(10)
title = params[:name].to_s.strip.first(15)
desc = params[:description].to_s.first(30)
color = params[:color] || "#ccc"
@ -29,7 +29,7 @@ class IssueTagsController < ApplicationController
if title.present?
if IssueTag.exists?(name: title, project_id: @project.id)
normal_status(-1, "标签已存在")
normal_status(-1, "项目标记已存在")
else
ActiveRecord::Base.transaction do
begin
@ -37,12 +37,12 @@ class IssueTagsController < ApplicationController
if issue_tag.save
# gitea_tag = Gitea::Labels::CreateService.new(current_user, @repository.try(:identifier), tag_params).call
# if gitea_tag && issue_tag.update_attributes(gid: gitea_tag["id"], gitea_url: gitea_tag["url"])
# normal_status(0, "标签创建成功")
normal_status(0, "项目标记创建成功!")
# else
# normal_status(-1, "标签创建失败")
# normal_status(-1, "项目标记创建失败")
# end
else
normal_status(-1, "标签创建失败")
normal_status(-1, "项目标记创建失败")
end
rescue => e
puts "create version release error: #{e.message}"
@ -51,7 +51,7 @@ class IssueTagsController < ApplicationController
end
end
else
normal_status(-1, "标签名称不能为空")
normal_status(-1, "项目标记名称不能为空")
end
end
@ -60,8 +60,8 @@ class IssueTagsController < ApplicationController
end
def update
title = params[:name]
desc = params[:description]
title = params[:name].to_s.strip.first(15)
desc = params[:description].to_s.first(30)
color = params[:color] || "#ccc"
tag_params = {
@ -71,19 +71,19 @@ class IssueTagsController < ApplicationController
}
if title.present?
if IssueTag.exists?(name: title, project_id: @project.id) && (@issue_tag.name != title)
normal_status(-1, "标签已存在")
normal_status(-1, "项目标记已存在")
else
ActiveRecord::Base.transaction do
begin
if @issue_tag.update_attributes(tag_params)
# gitea_tag = Gitea::Labels::UpdateService.new(current_user, @repository.try(:identifier),@issue_tag.try(:gid), tag_params).call
# if gitea_tag
# normal_status(0, "标签更新成功")
# normal_status(0, "项目标记更新成功")
# else
# normal_status(-1, "标签更新失败")
# normal_status(-1, "项目标记更新失败")
# end
else
normal_status(-1, "标签更新失败")
normal_status(-1, "项目标记更新失败")
end
rescue => e
puts "create version release error: #{e.message}"
@ -92,7 +92,7 @@ class IssueTagsController < ApplicationController
end
end
else
normal_status(-1, "标签名称不能为空")
normal_status(-1, "项目标记名称不能为空")
end
end
@ -102,12 +102,12 @@ class IssueTagsController < ApplicationController
if @issue_tag.destroy
# issue_tag = Gitea::Labels::DeleteService.new(@user, @repository.try(:identifier), @issue_tag.try(:gid)).call
# if issue_tag
# normal_status(0, "标签删除成功")
# normal_status(0, "项目标记删除成功")
# else
# normal_status(-1, "标签删除失败")
# normal_status(-1, "项目标记删除失败")
# end
else
normal_status(-1, "标签删除失败")
normal_status(-1, "项目标记删除失败")
end
rescue => e
puts "create version release error: #{e.message}"
@ -122,16 +122,16 @@ class IssueTagsController < ApplicationController
@user = @project.owner
end
def check_issue_permission
unless @project.member?(current_user) || current_user.admin?
normal_status(-1, "您没有权限")
def check_issue_tags_permission
unless @project.manager?(current_user) || current_user.admin?
return render_forbidden('你不是管理员,没有权限操作')
end
end
def set_issue_tag
@issue_tag = IssueTag.find_by_id(params[:id])
unless @issue_tag.present?
normal_status(-1, "标签不存在")
normal_status(-1, "项目标记不存在")
end
end

View File

@ -15,6 +15,7 @@ class IssuesController < ApplicationController
include TagChosenHelper
def index
@user_operate_issue = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user))
@user_admin_or_member = current_user.present? && current_user.logged? && (current_user.admin || @project.member?(current_user) || @project.is_public?)
issues = @project.issues.issue_issue.issue_index_includes
issues = issues.where(is_private: false) unless @user_admin_or_member
@ -125,9 +126,15 @@ class IssuesController < ApplicationController
end
end
if params[:issue_tag_ids].present?
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
else
return normal_status(-1, "请输入正确的标记。")
end
end
if params[:assigned_to_id].present?
Tiding.create!(user_id: params[:assigned_to_id], trigger_user_id: current_user.id,
@ -146,7 +153,7 @@ class IssuesController < ApplicationController
Rails.logger.info "[ATME] maybe to at such users: #{@atme_receivers.pluck(:login)}"
AtmeService.call(current_user, @atme_receivers, @issue) if @atme_receivers.size > 0
render json: {status: 0, message: "创建成", id: @issue.id}
render json: {status: 0, message: "创建成", id: @issue.id}
else
normal_status(-1, "创建失败")
end
@ -165,11 +172,17 @@ class IssuesController < ApplicationController
last_token = @issue.token
last_status_id = @issue.status_id
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists?
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
end
if params[:issue_tag_ids].present?
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
else
return normal_status(-1, "请输入正确的标记。")
end
end
issue_files = params[:attachment_ids]
@ -473,7 +486,8 @@ class IssuesController < ApplicationController
end
def operate_issue_permission
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || @project.is_public?)
@issue = Issue.find_by_id(params[:id]) unless @issue.present?
return render_forbidden("您没有权限进行此操作.") unless current_user.present? && current_user.logged? && (current_user.admin? || @project.member?(current_user) || (@project.is_public && @issue.nil?) || (@project.is_public && @issue.present? && @issue.author_id == current_user.id))
end
def export_issues(issues)

View File

@ -3,7 +3,7 @@ class MembersController < ApplicationController
before_action :load_project
before_action :find_user_with_id, only: %i[create remove change_role]
before_action :check_user_profile_completed, only: [:create]
before_action :operate!, except: %i[index]
before_action :operate!
before_action :check_member_exists!, only: %i[create]
before_action :check_member_not_exists!, only: %i[remove change_role]

View File

@ -2,6 +2,7 @@ class Oauth::BaseController < ActionController::Base
include RenderHelper
include LoginHelper
include ControllerRescueHandler
include LoggerHelper
# include LaboratoryHelper
skip_before_action :verify_authenticity_token
@ -11,6 +12,18 @@ class Oauth::BaseController < ActionController::Base
end
private
def tip_exception(status = -1, message)
raise Educoder::TipException.new(status, message)
end
def tip_show_exception(status = -2, message)
raise Educoder::TipException.new(status, message)
end
def tip_show(exception)
uid_logger("Tip show status is #{exception.status}, message is #{exception.message}")
render json: exception.tip_json
end
def session_user_id
# session[:user_id]
@ -48,4 +61,13 @@ class Oauth::BaseController < ActionController::Base
Rails.logger.info("[wechat] set session unionid: #{unionid}")
session[:unionid] = unionid
end
def session_edulogin
session[:edulogin]
end
def set_session_edulogin(login)
Rails.logger.info("[educoder] set sesstion edulogin: #{login}")
session[:edulogin] = login
end
end

View File

@ -1,4 +1,6 @@
class Oauth::EducoderController < Oauth::BaseController
include RegisterHelper
def bind
begin
login = params[:login]
@ -32,4 +34,41 @@ class Oauth::EducoderController < Oauth::BaseController
render_error(ex.message)
end
end
# 需要educoder那边设置回调地址
def create
begin
code = params['code'].to_s.strip
tip_exception("code不能为空") if code.blank?
new_user = false
result = EducoderOauth::Service.access_token(code)
result = EducoderOauth::Service.user_info(result[:access_token])
# 存在该用户
open_user = OpenUsers::Educoder.find_by(uid: result['login'])
if open_user.present? && open_user.user.present?
successful_authentication(open_user.user)
else
if current_user.blank? || !current_user.logged?
new_user = true
login = User.generate_login('E')
reg_result = autologin_register(login,"#{login}@forge.com", "Ec#{login}2021#", 'educoder', true)
if reg_result[:message].blank?
open_user = OpenUsers::Educoder.create!(user_id: reg_result[:user][:id], uid: result['login'], extra: result)
autosync_register_trustie(login, "Ec#{login}2021#", "#{login}@forge.com")
successful_authentication(open_user.user)
else
render_error(reg_result[:message])
end
else
OpenUsers::Educoder.create!(user: current_user, uid: result['login'], extra: result)
end
end
redirect_to root_path(new_user: new_user)
rescue Exception => ex
render_error(ex.message)
end
end
end

View File

@ -61,6 +61,7 @@ class OauthController < ApplicationController
login = params[:login]
email = params[:mail]
password = params[:password]
lastname = params[:lastname]
callback_url = params[:callback_url]
platform = params[:plathform] || 'educoder'
@ -72,8 +73,11 @@ class OauthController < ApplicationController
if result[:message].blank?
logger.info "[Oauth educoer] ====auto_register success"
user = User.find result[:user][:id]
successful_authentication(user)
user.update_column(:lastname, params[:lastname])
autosync_register_trustie(login, password, email, lastname)
OpenUsers::Educoder.create!(user: user, uid: user.login)
successful_authentication(user)
render json: { callback_url: callback_url }
# redirect_to callback_url

View File

@ -28,7 +28,7 @@ class Organizations::OrganizationsController < Organizations::BaseController
def create
ActiveRecord::Base.transaction do
tip_exception("无法使用以下关键词:#{organization_params[:name]},请重新命名") if ReversedKeyword.check_exists?(organization_params[:name])
Organizations::CreateForm.new(organization_params).validate!
Organizations::CreateForm.new(organization_params.merge(original_name: "")).validate!
@organization = Organizations::CreateService.call(current_user, organization_params)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
end
@ -39,14 +39,14 @@ class Organizations::OrganizationsController < Organizations::BaseController
def update
ActiveRecord::Base.transaction do
Organizations::CreateForm.new(organization_params).validate!
Organizations::CreateForm.new(organization_params.merge(original_name: @organization.login)).validate!
login = @organization.login
@organization.login = organization_params[:name] if organization_params[:name].present?
@organization.nickname = organization_params[:nickname] if organization_params[:nickname].present?
@organization.save!
sync_organization_extension!
Gitea::Organization::UpdateService.call(@organization.gitea_token, login, @organization.reload)
Gitea::Organization::UpdateService.call(current_user.gitea_token, login, @organization.reload)
Util.write_file(@image, avatar_path(@organization)) if params[:image].present?
end
rescue Exception => e
@ -57,10 +57,16 @@ class Organizations::OrganizationsController < Organizations::BaseController
def destroy
tip_exception("密码不正确") unless current_user.check_password?(password)
ActiveRecord::Base.transaction do
Gitea::Organization::DeleteService.call(@organization.gitea_token, @organization.login)
@organization.destroy!
gitea_destroy = Gitea::Organization::DeleteService.call(current_user.gitea_token, @organization.login)
if gitea_destroy[:status] == 204
@organization.destroy!
render_ok
elsif gitea_destroy[:status] == 500
tip_exception("当组织内含有仓库时,无法删除此组织")
else
tip_exception("")
end
end
render_ok
rescue Exception => e
uid_logger_error(e.message)
tip_exception(e.message)

View File

@ -18,7 +18,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
ActiveRecord::Base.transaction do
@team_user = TeamUser.build(@organization.id, @operate_user.id, @team.id)
@organization_user = OrganizationUser.build(@organization.id, @operate_user.id)
SendTemplateMessageJob.perform_later('OrganizationRole', @operate_user.id, @organization.id, @team.authorize_name) if Site.has_notice_menu?
SendTemplateMessageJob.perform_later('TeamJoined', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
Gitea::Organization::TeamUser::CreateService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
end
rescue Exception => e
@ -31,6 +31,7 @@ class Organizations::TeamUsersController < Organizations::BaseController
ActiveRecord::Base.transaction do
@team_user.destroy!
Gitea::Organization::TeamUser::DeleteService.call(@organization.gitea_token, @team.gtid, @operate_user.login)
SendTemplateMessageJob.perform_later('TeamLeft', @operate_user.id, @organization.id, @team.id) if Site.has_notice_menu?
org_team_users = @organization.team_users.where(user_id: @operate_user.id)
unless org_team_users.present?
@organization.organization_users.find_by(user_id: @operate_user.id).destroy!

View File

@ -4,15 +4,24 @@ class Organizations::TeamsController < Organizations::BaseController
before_action :check_user_can_edit_org, only: [:create, :update, :destroy]
def index
#if @organization.is_owner?(current_user) || current_user.admin?
@teams = @organization.teams
#else
# @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id})
#end
@is_admin = can_edit_org?
@teams = @teams.includes(:team_units, :team_users)
@teams = kaminari_paginate(@teams)
if params[:is_full].present?
if can_edit_org?
@teams = @organization.teams
else
@teams = []
end
else
#if @organization.is_owner?(current_user) || current_user.admin?
@teams = @organization.teams
#else
# @teams = @organization.teams.joins(:team_users).where(team_users: {user_id: current_user.id})
#end
@is_admin = can_edit_org?
@teams = @teams.includes(:team_units, :team_users)
@teams = kaminari_paginate(@teams)
end
end
def search
@ -34,8 +43,12 @@ class Organizations::TeamsController < Organizations::BaseController
def create
ActiveRecord::Base.transaction do
Organizations::CreateTeamForm.new(team_params).validate!
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
if @organization.teams.count >= 50
return render_forbidden("组织的团队数量已超过限制!")
else
Organizations::CreateTeamForm.new(team_params).validate!
@team = Organizations::Teams::CreateService.call(current_user, @organization, team_params)
end
end
rescue Exception => e
uid_logger_error(e.message)

View File

@ -12,7 +12,7 @@ class OwnersController < ApplicationController
def show
@owner = Owner.find_by(login: params[:id]) || Owner.find_by(id: params[:id])
return render_not_found unless @owner.present?
return render_ok(type: 'User') unless @owner.present?
# 组织
if @owner.is_a?(Organization)
return render_forbidden("没有查看组织的权限") if org_limited_condition || org_privacy_condition
@ -20,7 +20,7 @@ class OwnersController < ApplicationController
@is_admin = current_user.admin? || @owner.is_owner?(current_user.id)
@is_member = @owner.is_member?(current_user.id)
# 用户
else
elsif @owner.is_a?(User)
#待办事项,现在未做
if User.current.admin? || User.current.login == @owner.login
@waiting_applied_messages = @owner.applied_messages.waiting
@ -45,7 +45,6 @@ class OwnersController < ApplicationController
@projects_common_count = user_projects.common.size
@projects_mirrior_count = user_projects.mirror.size
@projects_sync_mirrior_count = user_projects.sync_mirror.size
puts @owner.as_json
end
end

View File

@ -3,7 +3,7 @@ class ProjectTrendsController < ApplicationController
before_action :check_project_public
def index
project_trends = @project.project_trends.preload(:user, trend: :user)
project_trends = @project.project_trends.preload(:user, trend: :user, project: :owner)
check_time = params[:time] #时间的筛选
check_type = params[:type] #动态类型的筛选,目前已知的有 Issue, PullRequest, Version

View File

@ -16,13 +16,13 @@ class ProjectsController < ApplicationController
menu.append(menu_hash_by_name("home"))
menu.append(menu_hash_by_name("code")) if @project.has_menu_permission("code")
menu.append(menu_hash_by_name("issues")) if @project.has_menu_permission("issues")
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls")
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki")
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops")
menu.append(menu_hash_by_name("pulls")) if @project.has_menu_permission("pulls") && @project.forge?
menu.append(menu_hash_by_name("devops")) if @project.has_menu_permission("devops") && @project.forge?
menu.append(menu_hash_by_name("versions")) if @project.has_menu_permission("versions")
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources")
menu.append(menu_hash_by_name("wiki")) if @project.has_menu_permission("wiki") && @project.forge?
menu.append(menu_hash_by_name("resources")) if @project.has_menu_permission("resources") && @project.forge?
menu.append(menu_hash_by_name("activity"))
menu.append(menu_hash_by_name("settings")) if current_user.admin? || @project.manager?(current_user)
menu.append(menu_hash_by_name("settings")) if (current_user.admin? || @project.manager?(current_user)) && @project.forge?
render json: menu
end
@ -82,8 +82,9 @@ class ProjectsController < ApplicationController
def branches
return @branches = [] unless @project.forge?
result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
@branches = result.is_a?(Hash) && result.key?(:status) ? [] : result
# result = Gitea::Repository::Branches::ListService.call(@owner, @project.identifier)
result = Gitea::Repository::Branches::ListNameService.call(@owner, @project.identifier)
@branches = result.is_a?(Hash) ? (result.key?(:status) ? [] : result["branch_name"]) : result
end
def branches_slice

View File

@ -56,6 +56,7 @@ class PullRequestsController < ApplicationController
end
def create
# return normal_status(-1, "您不是目标分支开发者,没有权限,请联系目标分支作者.") unless @project.operator?(current_user)
ActiveRecord::Base.transaction do
@pull_request, @gitea_pull_request = PullRequests::CreateService.call(current_user, @owner, @project, params)
if @gitea_pull_request[:status] == :success
@ -69,6 +70,8 @@ class PullRequestsController < ApplicationController
raise ActiveRecord::Rollback
end
end
rescue => e
normal_status(-1, e.message)
end
def edit
@ -78,6 +81,7 @@ class PullRequestsController < ApplicationController
end
def update
return render_forbidden("你没有权限操作.") unless @project.operator?(current_user)
if params[:title].nil?
normal_status(-1, "名称不能为空")
elsif params[:issue_tag_ids].nil?
@ -85,14 +89,21 @@ class PullRequestsController < ApplicationController
else
ActiveRecord::Base.transaction do
begin
return normal_status(-1, "title不能超过255个字符") if params[:title].length > 255
merge_params
@issue&.issue_tags_relates&.destroy_all if params[:issue_tag_ids].blank?
if params[:issue_tag_ids].present? && !@issue&.issue_tags_relates.where(issue_tag_id: params[:issue_tag_ids]).exists?
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
end
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
else
return normal_status(-1, "请输入正确的标记。")
end
end
if @issue.update_attributes(@issue_params)
@ -102,9 +113,16 @@ class PullRequestsController < ApplicationController
if gitea_pull[:status] === :success
if params[:issue_tag_ids].present?
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create(issue_id: @issue.id, issue_tag_id: tag)
end
if params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size > 1
return normal_status(-1, "最多只能创建一个标记。")
elsif params[:issue_tag_ids].is_a?(Array) && params[:issue_tag_ids].size == 1
@issue&.issue_tags_relates&.destroy_all
params[:issue_tag_ids].each do |tag|
IssueTagsRelate.create!(issue_id: @issue.id, issue_tag_id: tag)
end
else
return normal_status(-1, "请输入正确的标记。")
end
end
if params[:status_id].to_i == 5
@issue.issue_times.update_all(end_time: Time.now)
@ -197,7 +215,7 @@ class PullRequestsController < ApplicationController
def check_can_merge
target_head = params[:head] #源分支
target_base = params[:base] #目标分支
is_original = params[:is_original]
is_original = params[:is_original] || false
if target_head.blank? || target_base.blank?
normal_status(-2, "请选择分支")
elsif target_head === target_base && !is_original
@ -228,11 +246,11 @@ class PullRequestsController < ApplicationController
private
def load_pull_request
@pull_request = PullRequest.find params[:id]
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
end
def find_pull_request
@pull_request = PullRequest.find_by_id(params[:id])
@pull_request = @project.pull_requests.where(gitea_number: params[:id]).where.not(id: params[:id]).take || PullRequest.find_by_id(params[:id])
@issue = @pull_request&.issue
if @pull_request.blank?
normal_status(-1, "合并请求不存在")
@ -271,7 +289,7 @@ class PullRequestsController < ApplicationController
assigned_to_id: params[:assigned_to_id],
fixed_version_id: params[:fixed_version_id],
issue_tags_value: params[:issue_tag_ids].present? ? params[:issue_tag_ids].join(",") : "",
priority_id: params[:priority_id] || "2",
priority_id: params[:priority_id],
issue_classify: "pull_request",
issue_type: params[:issue_type] || "1",
tracker_id: 2,

View File

@ -64,7 +64,6 @@ class RepositoriesController < ApplicationController
def sub_entries
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
if @project.educoder?
if params[:type] === 'file'
@ -72,18 +71,35 @@ class RepositoriesController < ApplicationController
logger.info "######### sub_entries: #{@sub_entries}"
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = [{
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}]
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
else
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
begin
@sub_entries = Educoder::Repository::Entries::ListService.call(@project&.project_educoder&.repo_name, {path: file_path_uri})
if @sub_entries.blank? || @sub_entries['status'].to_i === -1
@sub_entries = Educoder::Repository::Entries::GetService.call(@project&.project_educoder&.repo_name, file_path_uri)
return render_error('该文件暂未开放,敬请期待.') if @sub_entries['status'].to_i === -1
tmp_entries = {
"content" => @sub_entries['data']['content'],
"type" => "blob"
}
@sub_entries = {
"trees"=>tmp_entries,
"commits" => [{}]
}
end
rescue
return render_error('该文件暂未开放,敬请期待.')
end
end
else
@path = Gitea.gitea_config[:domain]+"/#{@project.owner.login}/#{@project.identifier}/raw/branch/#{@ref}/"
interactor = Repositories::EntriesInteractor.call(@owner, @project.identifier, file_path_uri, ref: @ref)
if interactor.success?
result = interactor.result
@ -95,13 +111,17 @@ class RepositoriesController < ApplicationController
end
def commits
if params[:filepath].present?
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
if @project.educoder?
@commits = Educoder::Repository::Commits::ListService.call(@project&.project_educoder&.repo_name)
else
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
if params[:filepath].present?
file_path_uri = URI.parse(URI.encode(params[:filepath].to_s.strip))
@hash_commit = Gitea::Repository::Commits::FileListService.new(@owner.login, @project.identifier, file_path_uri,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
else
@hash_commit = Gitea::Repository::Commits::ListService.new(@owner.login, @project.identifier,
sha: params[:sha], page: params[:page], limit: params[:limit], token: current_user&.gitea_token).call
end
end
end
@ -112,8 +132,12 @@ class RepositoriesController < ApplicationController
def commit
@sha = params[:sha]
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
if @project.educoder?
return render_error('暂未开放,敬请期待.')
else
@commit = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token)
@commit_diff = Gitea::Repository::Commits::GetService.call(@owner.login, @repository.identifier, @sha, current_user&.gitea_token, {diff: true})
end
end
def tags
@ -123,7 +147,7 @@ class RepositoriesController < ApplicationController
end
def contributors
if params[:filepath].present?
if params[:filepath].present? || @project.educoder?
@contributors = []
else
@contributors = Gitea::Repository::Contributors::GetService.call(@owner, @repository.identifier)
@ -195,21 +219,26 @@ class RepositoriesController < ApplicationController
else
result = Gitea::Repository::Readme::GetService.call(@owner.login, @repository.identifier, params[:ref], current_user&.gitea_token)
end
@path = Gitea.gitea_config[:domain]+"/#{@owner.login}/#{@repository.identifier}/raw/branch/#{params[:ref]}/"
@readme = result[:status] === :success ? result[:body] : nil
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref])
@readme['content'] = decode64_content(@readme, @owner, @repository, params[:ref], @path)
render json: @readme.slice("type", "encoding", "size", "name", "path", "content", "sha")
rescue
render json: nil
end
def languages
render json: languages_precentagable
if @project.educoder?
render json: {}
else
render json: languages_precentagable
end
end
def archive
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{params[:archive]}"
archive_url = "/repos/#{@owner.login}/#{@repository.identifier}/archive/#{CGI.escape(params[:archive])}"
file_path = [domain, api_url, archive_url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("?") if @repository.hidden?
@ -223,11 +252,11 @@ class RepositoriesController < ApplicationController
domain = Gitea.gitea_config[:domain]
api_url = Gitea.gitea_config[:base_url]
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{params[:filepath]}?ref=#{params[:ref]}"
url = "/repos/#{@owner.login}/#{@repository.identifier}/raw/#{CGI.escape(params[:filepath])}?ref=#{CGI.escape(params[:ref])}"
file_path = [domain, api_url, url].join
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&") if @repository.hidden?
file_path = [file_path, "access_token=#{current_user&.gitea_token}"].join("&")
redirect_to URI.escape(file_path)
redirect_to file_path
end
private

View File

@ -4,6 +4,7 @@ class SettingsController < ApplicationController
get_add_menu
get_common_menu
get_personal_menu
get_third_party
get_top_system_notification
end
@ -40,6 +41,14 @@ class SettingsController < ApplicationController
end
end
def get_third_party
@third_party = []
@third_party << {
name: 'educoder',
url: EducoderOauth.oauth_url
}
end
def get_top_system_notification
@top_system_notification = SystemNotification.is_top.first
end

View File

@ -0,0 +1,9 @@
class TopicsController < ApplicationController
def index
return render_not_found("请输入正确的数据类型") unless params[:topic_type].present?
scope = Topic.with_single_type(params[:topic_type])
@topics = kaminari_paginate(scope)
end
end

View File

@ -6,7 +6,7 @@ class UsersController < ApplicationController
before_action :check_user_exist, only: [:show, :homepage_info,:projects, :watch_users, :fan_users, :hovercard]
before_action :require_login, only: %i[me list sync_user_info]
before_action :connect_to_ci_db, only: [:get_user_info]
before_action :convert_image!, only: [:update]
before_action :convert_image!, only: [:update, :update_image]
skip_before_action :check_sign, only: [:attachment_show]
def connect_to_ci_db(options={})
@ -32,7 +32,8 @@ class UsersController < ApplicationController
@waiting_applied_messages = @user.applied_messages.waiting
@common_applied_transfer_projects = AppliedTransferProject.where(owner_id: @user.id).common + AppliedTransferProject.where(owner_id: Organization.joins(team_users: :team).where(team_users: {user_id: @user.id}, teams: {authorize: %w(admin owner)} )).common
@common_applied_projects = AppliedProject.where(project_id: @user.full_admin_projects).common
@undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size + @common_applied_projects.size
#@undo_events = @waiting_applied_messages.size + @common_applied_transfer_projects.size + @common_applied_projects.size
@undo_events = @common_applied_transfer_projects.size + @common_applied_projects.size
else
@waiting_applied_messages = AppliedMessage.none
@common_applied_transfer_projects = AppliedTransferProject.none
@ -81,10 +82,21 @@ class UsersController < ApplicationController
Util.write_file(@image, avatar_path(@user)) if user_params[:image].present?
@user.attributes = user_params.except(:image)
unless @user.save
render_error(@user.errors.full_messages.join(", "))
render_error(-1, @user.errors.full_messages.join(", "))
end
end
def update_image
return render_not_found unless @user = User.find_by(login: params[:id]) || User.find_by_id(params[:id])
return render_forbidden unless User.current.logged? && (current_user&.admin? || current_user.id == @user.id)
Util.write_file(@image, avatar_path(@user))
return render_ok({message: '头像修改成功'})
rescue Exception => e
uid_logger_error(e.message)
render_error(-1, '头像修改失败!')
end
def me
@user = current_user
end
@ -275,7 +287,7 @@ class UsersController < ApplicationController
interactor = Gitea::User::UpdateInteractor.call(user.login, sync_params)
if interactor.success?
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_EDIT_INFO)
user.update!(password: params[:password], mail: params[:email], status: User::STATUS_ACTIVE)
render_ok
else
render_error(interactor.error)

View File

@ -1,2 +0,0 @@
build/
.github/

View File

@ -1,18 +0,0 @@
# EditorConfig is awesome: https://EditorConfig.org
# Top-most EditorConfig file
root = true
# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
[*.rb]
charset = utf-8
[*.md]
trim_trailing_whitespace = false

View File

@ -1 +0,0 @@
source/javascripts/lib/* linguist-vendored

View File

@ -1,22 +0,0 @@
---
name: Report a Bug
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Bug Description**
A clear and concise description of what the bug is and how to reproduce it.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Browser (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Last upstream Slate commit (run `git log --author="Robert Lord" | head -n 1`):**
Put the commit hash here

View File

@ -1,5 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Questions, Ideas, Discussions
url: https://github.com/slatedocs/slate/discussions
about: Ask and answer questions, and propose new features.

View File

@ -1,5 +0,0 @@
<!--
⚠️ 🚨 ⚠️ STOP AND READ THIS ⚠️ 🚨 ⚠️
👆👆 see that 'base fork' dropdown above? You should change it! The default value of "slatedocs/slate" submits your change to ALL USERS OF SLATE, not just your company. This is PROBABLY NOT WHAT YOU WANT.
-->

View File

@ -1,42 +0,0 @@
name: Build
on:
push:
branches: [ '*' ]
pull_request:
branches: [ '*' ]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: [2.3, 2.4, 2.5, 2.6, 2.7]
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
- uses: actions/cache@v2
with:
path: vendor/bundle
key: gems-${{ runner.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
gems-${{ runner.os }}-${{ matrix.ruby-version }}-
gems-${{ runner.os }}-
# necessary to get ruby 2.3 to work nicely with bundler vendor/bundle cache
# can remove once ruby 2.3 is no longer supported
- run: gem update --system
- run: bundle config set deployment 'true'
- name: bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- run: bundle exec middleman build

View File

@ -1,41 +0,0 @@
name: Deploy
on:
push:
branches: [ 'main' ]
jobs:
deploy:
runs-on: ubuntu-latest
env:
ruby-version: 2.5
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby-version }}
- uses: actions/cache@v2
with:
path: vendor/bundle
key: gems-${{ runner.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
gems-${{ runner.os }}-${{ matrix.ruby-version }}-
gems-${{ runner.os }}-
- run: bundle config set deployment 'true'
- name: bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- run: bundle exec middleman build
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
keep_files: true

View File

@ -1,50 +0,0 @@
name: Dev Deploy
on:
push:
branches: [ 'dev' ]
jobs:
deploy:
runs-on: ubuntu-latest
env:
ruby-version: 2.5
steps:
- uses: actions/checkout@v2
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ env.ruby-version }}
- uses: actions/cache@v2
with:
path: vendor/bundle
key: gems-${{ runner.os }}-${{ matrix.ruby-version }}-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
gems-${{ runner.os }}-${{ matrix.ruby-version }}-
gems-${{ runner.os }}-
- run: bundle config set deployment 'true'
- name: bundle install
run: |
bundle config path vendor/bundle
bundle install --jobs 4 --retry 3
- run: bundle exec middleman build
- name: Push to Docker Hub
uses: docker/build-push-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_KEY }}
repository: slatedocs/slate
tag_with_ref: true
- name: Deploy
uses: peaceiris/actions-gh-pages@v3.7.0-8
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
destination_dir: dev
publish_dir: ./build
keep_files: true

View File

@ -1,22 +0,0 @@
name: Publish Docker image
on:
release:
types: [published]
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Push to Docker Hub
uses: docker/build-push-action@v1
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_KEY }}
repository: slatedocs/slate
tag_with_ref: true
tags: latest

View File

@ -1,27 +0,0 @@
*.gem
*.rbc
.bundle
.config
coverage
InstalledFiles
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
*.DS_STORE
build/
.cache
.vagrant
.sass-cache
# YARD artifacts
.yardoc
_yardoc
doc/
.idea/
# Vagrant artifacts
ubuntu-*-console.log

View File

@ -1,254 +0,0 @@
# Changelog
## Version 2.8.0
*October 27, 2020*
* Remove last trailing newline when using the copy code button
* Rework docker image and make available at slatedocs/slate
* Improve Dockerfile layout to improve caching (thanks @micvbang)
* Bump rouge from 3.20 to 3.24
* Bump nokogiri from 1.10.9 to 1.10.10
* Bump middleman from 4.3.8 to 4.3.11
* Bump lunr.js from 2.3.8 to 2.3.9
## Version 2.7.1
*August 13, 2020*
* __[security]__ Bumped middleman from 4.3.7 to 4.3.8
_Note_: Slate uses redcarpet, not kramdown, for rendering markdown to HTML, and so was unaffected by the security vulnerability in middleman.
If you have changed slate to use kramdown, and with GFM, you may need to install the `kramdown-parser-gfm` gem.
## Version 2.7.0
*June 21, 2020*
* __[security]__ Bumped rack in Gemfile.lock from 2.2.2 to 2.2.3
* Bumped bundled jQuery from 3.2.1 to 3.5.1
* Bumped bundled lunr from 0.5.7 to 2.3.8
* Bumped imagesloaded from 3.1.8 to 4.1.4
* Bumped rouge from 3.17.0 to 3.20.0
* Bumped redcarpet from 3.4.0 to 3.5.0
* Fix color of highlighted code being unreadable when printing page
* Add clipboard icon for "Copy to Clipboard" functionality to code boxes (see note below)
* Fix handling of ToC selectors that contain punctutation (thanks @gruis)
* Fix language bar truncating languages that overflow screen width
* Strip HTML tags from ToC title before displaying it in title bar in JS (backup to stripping done in Ruby code) (thanks @atic)
To enable the new clipboard icon, you need to add `code_clipboard: true` to the frontmatter of source/index.html.md.
See [this line](https://github.com/slatedocs/slate/blame/main/source/index.html.md#L19) for an example of usage.
## Version 2.6.1
*May 30, 2020*
* __[security]__ update child dependency activesupport in Gemfile.lock to 5.4.2.3
* Update Middleman in Gemfile.lock to 4.3.7
* Replace Travis-CI with GitHub actions for continuous integration
* Replace Spectrum with GitHub discussions
## Version 2.6.0
*May 18, 2020*
__Note__: 2.5.0 was "pulled" due to a breaking bug discovered after release. It is recommended to skip it, and move straight to 2.6.0.
* Fix large whitespace gap in middle column for sections with codeblocks
* Fix highlighted code elements having a different background than rest of code block
* Change JSON keys to have a different font color than their values
* Disable asset hashing for woff and woff2 elements due to middleman bug breaking woff2 asset hashing in general
* Move Dockerfile to Debian from Alpine
* Converted repo to a [GitHub template](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-template-repository)
* Update sassc to 2.3.0 in Gemfile.lock
## Version 2.5.0
*May 8, 2020*
* __[security]__ update nokogiri to ~> 1.10.8
* Update links in example docs to https://github.com/slatedocs/slate from https://github.com/lord/slate
* Update LICENSE to include full Apache 2.0 text
* Test slate against Ruby 2.5 and 2.6 on Travis-CI
* Update Vagrantfile to use Ubuntu 18.04 (thanks @bradthurber)
* Parse arguments and flags for deploy.sh on script start, instead of potentially after building source files
* Install nodejs inside Vagrantfile (thanks @fernandoaguilar)
* Add Dockerfile for running slate (thanks @redhatxl)
* update middleman-syntax and rouge to ~>3.2
* update middleman to 4.3.6
## Version 2.4.0
*October 19, 2019*
- Move repository from lord/slate to slatedocs/slate
- Fix documentation to point at new repo link, thanks to [Arun](https://github.com/slash-arun), [Gustavo Gawryszewski](https://github.com/gawry), and [Daniel Korbit](https://github.com/danielkorbit)
- Update `nokogiri` to 1.10.4
- Update `ffi` in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
- Update `rack` to 2.0.7 in `Gemfile.lock` to fix security warnings, thanks to [Grey Baker](https://github.com/greysteil) and [jakemack](https://github.com/jakemack)
- Update middleman to `4.3` and relax constraints on middleman related gems, thanks to [jakemack](https://github.com/jakemack)
- Add sass gem, thanks to [jakemack](https://github.com/jakemack)
- Activate `asset_cache` in middleman to improve cacheability of static files, thanks to [Sam Gilman](https://github.com/thenengah)
- Update to using bundler 2 for `Gemfile.lock`, thanks to [jakemack](https://github.com/jakemack)
## Version 2.3.1
*July 5, 2018*
- Update `sprockets` in `Gemfile.lock` to fix security warnings
## Version 2.3
*July 5, 2018*
- Allows strikethrough in markdown by default.
- Upgrades jQuery to 3.2.1, thanks to [Tomi Takussaari](https://github.com/TomiTakussaari)
- Fixes invalid HTML in `layout.erb`, thanks to [Eric Scouten](https://github.com/scouten) for pointing out
- Hopefully fixes Vagrant memory issues, thanks to [Petter Blomberg](https://github.com/p-blomberg) for the suggestion
- Cleans HTML in headers before setting `document.title`, thanks to [Dan Levy](https://github.com/justsml)
- Allows trailing whitespace in markdown files, thanks to [Samuel Cousin](https://github.com/kuzyn)
- Fixes pushState/replaceState problems with scrolling not changing the document hash, thanks to [Andrey Fedorov](https://github.com/anfedorov)
- Removes some outdated examples, thanks [@al-tr](https://github.com/al-tr), [Jerome Dahdah](https://github.com/jdahdah), and [Ricardo Castro](https://github.com/mccricardo)
- Fixes `nav-padding` bug, thanks [Jerome Dahdah](https://github.com/jdahdah)
- Code style fixes thanks to [Sebastian Zaremba](https://github.com/vassyz)
- Nokogiri version bump thanks to [Grey Baker](https://github.com/greysteil)
- Fix to default `index.md` text thanks to [Nick Busey](https://github.com/NickBusey)
Thanks to everyone who contributed to this release!
## Version 2.2
*January 19, 2018*
- Fixes bugs with some non-roman languages not generating unique headers
- Adds editorconfig, thanks to [Jay Thomas](https://github.com/jaythomas)
- Adds optional `NestingUniqueHeadCounter`, thanks to [Vladimir Morozov](https://github.com/greenhost87)
- Small fixes to typos and language, thx [Emir Ribić](https://github.com/ribice), [Gregor Martynus](https://github.com/gr2m), and [Martius](https://github.com/martiuslim)!
- Adds links to Spectrum chat for questions in README and ISSUE_TEMPLATE
## Version 2.1
*October 30, 2017*
- Right-to-left text stylesheet option, thanks to [Mohammad Hossein Rabiee](https://github.com/mhrabiee)
- Fix for HTML5 history state bug, thanks to [Zach Toolson](https://github.com/ztoolson)
- Small styling changes, typo fixes, small bug fixes from [Marian Friedmann](https://github.com/rnarian), [Ben Wilhelm](https://github.com/benwilhelm), [Fouad Matin](https://github.com/fouad), [Nicolas Bonduel](https://github.com/NicolasBonduel), [Christian Oliff](https://github.com/coliff)
Thanks to everyone who submitted PRs for this version!
## Version 2.0
*July 17, 2017*
- All-new statically generated table of contents
- Should be much faster loading and scrolling for large pages
- Smaller Javascript file sizes
- Avoids the problem with the last link in the ToC not ever highlighting if the section was shorter than the page
- Fixes control-click not opening in a new page
- Automatically updates the HTML title as you scroll
- Updated design
- New default colors!
- New spacings and sizes!
- System-default typefaces, just like GitHub
- Added search input delay on large corpuses to reduce lag
- We even bumped the major version cause hey, why not?
- Various small bug fixes
Thanks to everyone who helped debug or wrote code for this version! It was a serious community effort, and I couldn't have done it alone.
## Version 1.5
*February 23, 2017*
- Add [multiple tabs per programming language](https://github.com/lord/slate/wiki/Multiple-language-tabs-per-programming-language) feature
- Upgrade Middleman to add Ruby 1.4.0 compatibility
- Switch default code highlighting color scheme to better highlight JSON
- Various small typo and bug fixes
## Version 1.4
*November 24, 2016*
- Upgrade Middleman and Rouge gems, should hopefully solve a number of bugs
- Update some links in README
- Fix broken Vagrant startup script
- Fix some problems with deploy.sh help message
- Fix bug with language tabs not hiding properly if no error
- Add `!default` to SASS variables
- Fix bug with logo margin
- Bump tested Ruby versions in .travis.yml
## Version 1.3.3
*June 11, 2016*
Documentation and example changes.
## Version 1.3.2
*February 3, 2016*
A small bugfix for slightly incorrect background colors on code samples in some cases.
## Version 1.3.1
*January 31, 2016*
A small bugfix for incorrect whitespace in code blocks.
## Version 1.3
*January 27, 2016*
We've upgraded Middleman and a number of other dependencies, which should fix quite a few bugs.
Instead of `rake build` and `rake deploy`, you should now run `bundle exec middleman build --clean` to build your server, and `./deploy.sh` to deploy it to Github Pages.
## Version 1.2
*June 20, 2015*
**Fixes:**
- Remove crash on invalid languages
- Update Tocify to scroll to the highlighted header in the Table of Contents
- Fix variable leak and update search algorithms
- Update Python examples to be valid Python
- Update gems
- More misc. bugfixes of Javascript errors
- Add Dockerfile
- Remove unused gems
- Optimize images, fonts, and generated asset files
- Add chinese font support
- Remove RedCarpet header ID patch
- Update language tabs to not disturb existing query strings
## Version 1.1
*July 27, 2014*
**Fixes:**
- Finally, a fix for the redcarpet upgrade bug
## Version 1.0
*July 2, 2014*
[View Issues](https://github.com/tripit/slate/issues?milestone=1&state=closed)
**Features:**
- Responsive designs for phones and tablets
- Started tagging versions
**Fixes:**
- Fixed 'unrecognized expression' error
- Fixed #undefined hash bug
- Fixed bug where the current language tab would be unselected
- Fixed bug where tocify wouldn't highlight the current section while searching
- Fixed bug where ids of header tags would have special characters that caused problems
- Updated layout so that pages with disabled search wouldn't load search.js
- Cleaned up Javascript

View File

@ -1,46 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@lord.io. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
[homepage]: http://contributor-covenant.org
[version]: http://contributor-covenant.org/version/1/4/

View File

@ -1,12 +0,0 @@
ruby '>=2.3.1'
source 'https://gems.ruby-china.com'
# Middleman
gem 'middleman', '~>4.3'
gem 'middleman-syntax', '~> 3.2'
gem 'middleman-autoprefixer', '~> 2.7'
gem 'middleman-sprockets', '~> 4.1'
gem 'rouge', '~> 3.21'
gem 'redcarpet', '~> 3.5.0'
gem 'nokogiri', '~> 1.10.8'
gem 'sass'

View File

@ -1,136 +0,0 @@
GEM
remote: https://gems.ruby-china.com/
specs:
activesupport (5.2.4.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
autoprefixer-rails (9.5.1.1)
execjs
backports (3.18.2)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.1.7)
contracts (0.13.0)
dotenv (2.7.6)
erubis (2.7.0)
execjs (2.7.0)
fast_blank (1.0.0)
fastimage (2.2.0)
ffi (1.13.1)
haml (5.1.2)
temple (>= 0.8.0)
tilt
hamster (3.0.0)
concurrent-ruby (~> 1.0)
hashie (3.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
kramdown (2.3.0)
rexml
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
memoist (0.16.2)
middleman (4.3.11)
coffee-script (~> 2.2)
haml (>= 4.0.5)
kramdown (>= 2.3.0)
middleman-cli (= 4.3.11)
middleman-core (= 4.3.11)
middleman-autoprefixer (2.10.1)
autoprefixer-rails (~> 9.1)
middleman-core (>= 3.3.3)
middleman-cli (4.3.11)
thor (>= 0.17.0, < 2.0)
middleman-core (4.3.11)
activesupport (>= 4.2, < 6.0)
addressable (~> 2.3)
backports (~> 3.6)
bundler
contracts (~> 0.13.0)
dotenv
erubis
execjs (~> 2.0)
fast_blank
fastimage (~> 2.0)
hamster (~> 3.0)
hashie (~> 3.4)
i18n (~> 0.9.0)
listen (~> 3.0.0)
memoist (~> 0.14)
padrino-helpers (~> 0.13.0)
parallel
rack (>= 1.4.5, < 3)
sassc (~> 2.0)
servolux
tilt (~> 2.0.9)
uglifier (~> 3.0)
middleman-sprockets (4.1.1)
middleman-core (~> 4.0)
sprockets (>= 3.0)
middleman-syntax (3.2.0)
middleman-core (>= 3.2)
rouge (~> 3.2)
mini_portile2 (2.4.0)
minitest (5.14.2)
nokogiri (1.10.10)
mini_portile2 (~> 2.4.0)
padrino-helpers (0.13.3.4)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.13.3.4)
tilt (>= 1.4.1, < 3)
padrino-support (0.13.3.4)
activesupport (>= 3.1)
parallel (1.19.2)
public_suffix (4.0.6)
rack (2.2.3)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
redcarpet (3.5.0)
rexml (3.2.4)
rouge (3.24.0)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sassc (2.4.0)
ffi (~> 1.9)
servolux (0.13.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
temple (0.8.2)
thor (1.0.1)
thread_safe (0.3.6)
tilt (2.0.10)
tzinfo (1.2.7)
thread_safe (~> 0.1)
uglifier (3.2.0)
execjs (>= 0.3.0, < 3)
PLATFORMS
ruby
DEPENDENCIES
middleman (~> 4.3)
middleman-autoprefixer (~> 2.7)
middleman-sprockets (~> 4.1)
middleman-syntax (~> 3.2)
nokogiri (~> 1.10.8)
redcarpet (~> 3.5.0)
rouge (~> 3.21)
sass
RUBY VERSION
ruby 2.3.3p222
BUNDLED WITH
2.1.4

View File

@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -1,81 +0,0 @@
<p align="center">
<img src="https://raw.githubusercontent.com/slatedocs/img/main/logo-slate.png" alt="Slate: API Documentation Generator" width="226">
<br>
<a href="https://github.com/slatedocs/slate/actions?query=workflow%3ABuild+branch%3Amain"><img src="https://github.com/slatedocs/slate/workflows/Build/badge.svg?branch=main" alt="Build Status"></a>
</p>
<p align="center">Slate helps you create beautiful, intelligent, responsive API documentation.</p>
<p align="center"><img src="https://raw.githubusercontent.com/slatedocs/img/main/screenshot-slate.png" width=700 alt="Screenshot of Example Documentation created with Slate"></p>
<p align="center"><em>The example above was created with Slate. Check it out at <a href="https://slatedocs.github.io/slate">slatedocs.github.io/slate</a>.</em></p>
Features
------------
* **Clean, intuitive design** — With Slate, the description of your API is on the left side of your documentation, and all the code examples are on the right side. Inspired by [Stripe's](https://stripe.com/docs/api) and [PayPal's](https://developer.paypal.com/webapps/developer/docs/api/) API docs. Slate is responsive, so it looks great on tablets, phones, and even in print.
* **Everything on a single page** — Gone are the days when your users had to search through a million pages to find what they wanted. Slate puts the entire documentation on a single page. We haven't sacrificed linkability, though. As you scroll, your browser's hash will update to the nearest header, so linking to a particular point in the documentation is still natural and easy.
* **Slate is just Markdown** — When you write docs with Slate, you're just writing Markdown, which makes it simple to edit and understand. Everything is written in Markdown — even the code samples are just Markdown code blocks.
* **Write code samples in multiple languages** — If your API has bindings in multiple programming languages, you can easily put in tabs to switch between them. In your document, you'll distinguish different languages by specifying the language name at the top of each code block, just like with GitHub Flavored Markdown.
* **Out-of-the-box syntax highlighting** for [over 100 languages](https://github.com/jneen/rouge/wiki/List-of-supported-languages-and-lexers), no configuration required.
* **Automatic, smoothly scrolling table of contents** on the far left of the page. As you scroll, it displays your current position in the document. It's fast, too. We're using Slate at TripIt to build documentation for our new API, where our table of contents has over 180 entries. We've made sure that the performance remains excellent, even for larger documents.
* **Let your users update your documentation for you** — By default, your Slate-generated documentation is hosted in a public GitHub repository. Not only does this mean you get free hosting for your docs with GitHub Pages, but it also makes it simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don't want to use GitHub, you're also welcome to host your docs elsewhere.
* **RTL Support** Full right-to-left layout for RTL languages such as Arabic, Persian (Farsi), Hebrew etc.
Getting started with Slate is super easy! Simply press the green "use this template" button above and follow the instructions below. Or, if you'd like to check out what Slate is capable of, take a look at the [sample docs](https://slatedocs.github.io/slate/).
Getting Started with Slate
------------------------------
To get started with Slate, please check out the [Getting Started](https://github.com/slatedocs/slate/wiki#getting-started)
section in our [wiki](https://github.com/slatedocs/slate/wiki).
We support running Slate in three different ways:
* [Natively](https://github.com/slatedocs/slate/wiki/Using-Slate-Natively)
* [Using Vagrant](https://github.com/slatedocs/slate/wiki/Using-Slate-in-Vagrant)
* [Using Docker](https://github.com/slatedocs/slate/wiki/Using-Slate-in-Docker)
Companies Using Slate
---------------------------------
* [NASA](https://api.nasa.gov)
* [Sony](http://developers.cimediacloud.com)
* [Best Buy](https://bestbuyapis.github.io/api-documentation/)
* [Travis-CI](https://docs.travis-ci.com/api/)
* [Greenhouse](https://developers.greenhouse.io/harvest.html)
* [WooCommerce](http://woocommerce.github.io/woocommerce-rest-api-docs/)
* [Dwolla](https://docs.dwolla.com/)
* [Clearbit](https://clearbit.com/docs)
* [Coinbase](https://developers.coinbase.com/api)
* [Parrot Drones](http://developer.parrot.com/docs/bebop/)
* [Scale](https://docs.scaleapi.com/)
You can view more in [the list on the wiki](https://github.com/slatedocs/slate/wiki/Slate-in-the-Wild).
Questions? Need Help? Found a bug?
--------------------
If you've got questions about setup, deploying, special feature implementation in your fork, or just want to chat with the developer, please feel free to [start a thread in our Discussions tab](https://github.com/slatedocs/slate/discussions)!
Found a bug with upstream Slate? Go ahead and [submit an issue](https://github.com/slatedocs/slate/issues). And, of course, feel free to submit pull requests with bug fixes or changes to the `dev` branch.
Contributors
--------------------
Slate was built by [Robert Lord](https://lord.io) while at [TripIt](https://www.tripit.com/). The project is now maintained by [Matthew Peveler](https://github.com/MasterOdin) and [Mike Ralphson](https://github.com/MikeRalphson).
Thanks to the following people who have submitted major pull requests:
- [@chrissrogers](https://github.com/chrissrogers)
- [@bootstraponline](https://github.com/bootstraponline)
- [@realityking](https://github.com/realityking)
- [@cvkef](https://github.com/cvkef)
Also, thanks to [Sauce Labs](http://saucelabs.com) for sponsoring the development of the responsive styles.

View File

@ -1,46 +0,0 @@
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/bionic64"
config.vm.network :forwarded_port, guest: 4567, host: 4567
config.vm.provider "virtualbox" do |vb|
vb.memory = "2048"
end
config.vm.provision "bootstrap",
type: "shell",
inline: <<-SHELL
# add nodejs v12 repository
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
sudo apt-get update
sudo apt-get install -yq ruby ruby-dev
sudo apt-get install -yq pkg-config build-essential nodejs git libxml2-dev libxslt-dev
sudo apt-get autoremove -yq
gem install --no-ri --no-rdoc bundler
SHELL
# add the local user git config to the vm
config.vm.provision "file", source: "~/.gitconfig", destination: ".gitconfig"
config.vm.provision "install",
type: "shell",
privileged: false,
inline: <<-SHELL
echo "=============================================="
echo "Installing app dependencies"
cd /vagrant
bundle config build.nokogiri --use-system-libraries
bundle install
SHELL
config.vm.provision "run",
type: "shell",
privileged: false,
run: "always",
inline: <<-SHELL
echo "=============================================="
echo "Starting up middleman at http://localhost:4567"
echo "If it does not come up, check the ~/middleman.log file for any error messages"
cd /vagrant
bundle exec middleman server --watcher-force-polling --watcher-latency=1 &> ~/middleman.log &
SHELL
end

View File

@ -1,65 +0,0 @@
set :build_dir, '../../../public/docs/'
# Unique header generation
require './lib/unique_head.rb'
# Markdown
set :markdown_engine, :redcarpet
set :markdown,
fenced_code_blocks: true,
smartypants: true,
disable_indented_code_blocks: true,
prettify: true,
strikethrough: true,
tables: true,
with_toc_data: true,
no_intra_emphasis: true,
renderer: UniqueHeadCounter
# Assets
set :css_dir, 'stylesheets'
set :js_dir, 'javascripts'
set :images_dir, 'images'
set :fonts_dir, 'fonts'
# Activate the syntax highlighter
activate :syntax
ready do
require './lib/monokai_sublime_slate.rb'
require './lib/multilang.rb'
end
activate :sprockets
activate :autoprefixer do |config|
config.browsers = ['last 2 version', 'Firefox ESR']
config.cascade = false
config.inline = true
end
# Github pages require relative links
activate :relative_assets
set :relative_links, true
# Build Configuration
configure :build do
# We do want to hash woff and woff2 as there's a bug where woff2 will use
# woff asset hash which breaks things. Trying to use a combination of ignore and
# rewrite_ignore does not work as it conflicts weirdly with relative_assets. Disabling
# the .woff2 extension only does not work as .woff will still activate it so have to
# have both. See https://github.com/slatedocs/slate/issues/1171 for more details.
activate :asset_hash, :exts => app.config[:asset_extensions] - %w[.woff .woff2]
# If you're having trouble with Middleman hanging, commenting
# out the following two lines has been known to help
activate :minify_css
activate :minify_javascript
# activate :gzip
end
# Deploy Configuration
# If you want Middleman to listen on a different port, you can set that below
set :port, 4567
helpers do
require './lib/toc_data.rb'
end

View File

@ -1,226 +0,0 @@
#!/usr/bin/env bash
set -o errexit #abort if any command fails
me=$(basename "$0")
help_message="\
Usage: $me [-c FILE] [<options>]
Deploy generated files to a git branch.
Options:
-h, --help Show this help information.
-v, --verbose Increase verbosity. Useful for debugging.
-e, --allow-empty Allow deployment of an empty directory.
-m, --message MESSAGE Specify the message used when committing on the
deploy branch.
-n, --no-hash Don't append the source commit's hash to the deploy
commit's message.
--source-only Only build but not push
--push-only Only push but not build
"
run_build() {
bundle exec middleman build --clean
}
parse_args() {
# Set args from a local environment file.
if [ -e ".env" ]; then
source .env
fi
# Parse arg flags
# If something is exposed as an environment variable, set/overwrite it
# here. Otherwise, set/overwrite the internal variable instead.
while : ; do
if [[ $1 = "-h" || $1 = "--help" ]]; then
echo "$help_message"
exit 0
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
verbose=true
shift
elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
allow_empty=true
shift
elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
commit_message=$2
shift 2
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
GIT_DEPLOY_APPEND_HASH=false
shift
elif [[ $1 = "--source-only" ]]; then
source_only=true
shift
elif [[ $1 = "--push-only" ]]; then
push_only=true
shift
else
break
fi
done
if [ ${source_only} ] && [ ${push_only} ]; then
>&2 echo "You can only specify one of --source-only or --push-only"
exit 1
fi
# Set internal option vars from the environment and arg flags. All internal
# vars should be declared here, with sane defaults if applicable.
# Source directory & target branch.
deploy_directory=build
deploy_branch=gh-pages
#if no user identity is already set in the current git environment, use this:
default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
default_email=${GIT_DEPLOY_EMAIL:-}
#repository to deploy to. must be readable and writable.
repo=origin
#append commit hash to the end of message by default
append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
}
main() {
enable_expanded_output
if ! git diff --exit-code --quiet --cached; then
echo Aborting due to uncommitted changes in the index >&2
return 1
fi
commit_title=`git log -n 1 --format="%s" HEAD`
commit_hash=` git log -n 1 --format="%H" HEAD`
#default commit message uses last title if a custom one is not supplied
if [[ -z $commit_message ]]; then
commit_message="publish: $commit_title"
fi
#append hash to commit message unless no hash flag was found
if [ $append_hash = true ]; then
commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
fi
previous_branch=`git rev-parse --abbrev-ref HEAD`
if [ ! -d "$deploy_directory" ]; then
echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
return 1
fi
# must use short form of flag in ls for compatibility with macOS and BSD
if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
return 1
fi
if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
# deploy_branch exists in $repo; make sure we have the latest version
disable_expanded_output
git fetch --force $repo $deploy_branch:$deploy_branch
enable_expanded_output
fi
# check if deploy_branch exists locally
if git show-ref --verify --quiet "refs/heads/$deploy_branch"
then incremental_deploy
else initial_deploy
fi
restore_head
}
initial_deploy() {
git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
git --work-tree "$deploy_directory" add --all
commit+push
}
incremental_deploy() {
#make deploy_branch the current branch
git symbolic-ref HEAD refs/heads/$deploy_branch
#put the previously committed contents of deploy_branch into the index
git --work-tree "$deploy_directory" reset --mixed --quiet
git --work-tree "$deploy_directory" add --all
set +o errexit
diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
set -o errexit
case $diff in
0) echo No changes to files in $deploy_directory. Skipping commit.;;
1) commit+push;;
*)
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
return $diff
;;
esac
}
commit+push() {
set_user_id
git --work-tree "$deploy_directory" commit -m "$commit_message"
disable_expanded_output
#--quiet is important here to avoid outputting the repo URL, which may contain a secret token
git push --quiet $repo $deploy_branch
enable_expanded_output
}
#echo expanded commands as they are executed (for debugging)
enable_expanded_output() {
if [ $verbose ]; then
set -o xtrace
set +o verbose
fi
}
#this is used to avoid outputting the repo URL, which may contain a secret token
disable_expanded_output() {
if [ $verbose ]; then
set +o xtrace
set -o verbose
fi
}
set_user_id() {
if [[ -z `git config user.name` ]]; then
git config user.name "$default_username"
fi
if [[ -z `git config user.email` ]]; then
git config user.email "$default_email"
fi
}
restore_head() {
if [[ $previous_branch = "HEAD" ]]; then
#we weren't on any branch before, so just set HEAD back to the commit it was on
git update-ref --no-deref HEAD $commit_hash $deploy_branch
else
git symbolic-ref HEAD refs/heads/$previous_branch
fi
git reset --mixed
}
filter() {
sed -e "s|$repo|\$repo|g"
}
sanitize() {
"$@" 2> >(filter 1>&2) | filter
}
parse_args "$@"
if [[ ${source_only} ]]; then
run_build
elif [[ ${push_only} ]]; then
main "$@"
else
run_build
main "$@"
fi

View File

@ -1,148 +0,0 @@
{
"IcoMoonType": "selection",
"icons": [
{
"icon": {
"paths": [
"M438.857 73.143q119.429 0 220.286 58.857t159.714 159.714 58.857 220.286-58.857 220.286-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857zM512 785.714v-108.571q0-8-5.143-13.429t-12.571-5.429h-109.714q-7.429 0-13.143 5.714t-5.714 13.143v108.571q0 7.429 5.714 13.143t13.143 5.714h109.714q7.429 0 12.571-5.429t5.143-13.429zM510.857 589.143l10.286-354.857q0-6.857-5.714-10.286-5.714-4.571-13.714-4.571h-125.714q-8 0-13.714 4.571-5.714 3.429-5.714 10.286l9.714 354.857q0 5.714 5.714 10t13.714 4.286h105.714q8 0 13.429-4.286t6-10z"
],
"attrs": [],
"isMulticolor": false,
"tags": [
"exclamation-circle"
],
"defaultCode": 61546,
"grid": 14
},
"attrs": [],
"properties": {
"id": 100,
"order": 4,
"prevSize": 28,
"code": 58880,
"name": "exclamation-sign",
"ligatures": ""
},
"setIdx": 0,
"iconIdx": 0
},
{
"icon": {
"paths": [
"M585.143 786.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-54.857v-292.571q0-8-5.143-13.143t-13.143-5.143h-182.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h54.857v182.857h-54.857q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h256q8 0 13.143-5.143t5.143-13.143zM512 274.286v-91.429q0-8-5.143-13.143t-13.143-5.143h-109.714q-8 0-13.143 5.143t-5.143 13.143v91.429q0 8 5.143 13.143t13.143 5.143h109.714q8 0 13.143-5.143t5.143-13.143zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"
],
"attrs": [],
"isMulticolor": false,
"tags": [
"info-circle"
],
"defaultCode": 61530,
"grid": 14
},
"attrs": [],
"properties": {
"id": 85,
"order": 3,
"name": "info-sign",
"prevSize": 28,
"code": 58882
},
"setIdx": 0,
"iconIdx": 2
},
{
"icon": {
"paths": [
"M733.714 419.429q0-16-10.286-26.286l-52-51.429q-10.857-10.857-25.714-10.857t-25.714 10.857l-233.143 232.571-129.143-129.143q-10.857-10.857-25.714-10.857t-25.714 10.857l-52 51.429q-10.286 10.286-10.286 26.286 0 15.429 10.286 25.714l206.857 206.857q10.857 10.857 25.714 10.857 15.429 0 26.286-10.857l310.286-310.286q10.286-10.286 10.286-25.714zM877.714 512q0 119.429-58.857 220.286t-159.714 159.714-220.286 58.857-220.286-58.857-159.714-159.714-58.857-220.286 58.857-220.286 159.714-159.714 220.286-58.857 220.286 58.857 159.714 159.714 58.857 220.286z"
],
"attrs": [],
"isMulticolor": false,
"tags": [
"check-circle"
],
"defaultCode": 61528,
"grid": 14
},
"attrs": [],
"properties": {
"id": 83,
"order": 9,
"prevSize": 28,
"code": 58886,
"name": "ok-sign"
},
"setIdx": 0,
"iconIdx": 6
},
{
"icon": {
"paths": [
"M658.286 475.429q0-105.714-75.143-180.857t-180.857-75.143-180.857 75.143-75.143 180.857 75.143 180.857 180.857 75.143 180.857-75.143 75.143-180.857zM950.857 950.857q0 29.714-21.714 51.429t-51.429 21.714q-30.857 0-51.429-21.714l-196-195.429q-102.286 70.857-228 70.857-81.714 0-156.286-31.714t-128.571-85.714-85.714-128.571-31.714-156.286 31.714-156.286 85.714-128.571 128.571-85.714 156.286-31.714 156.286 31.714 128.571 85.714 85.714 128.571 31.714 156.286q0 125.714-70.857 228l196 196q21.143 21.143 21.143 51.429z"
],
"width": 951,
"attrs": [],
"isMulticolor": false,
"tags": [
"search"
],
"defaultCode": 61442,
"grid": 14
},
"attrs": [],
"properties": {
"id": 2,
"order": 1,
"prevSize": 28,
"code": 58887,
"name": "icon-search"
},
"setIdx": 0,
"iconIdx": 7
}
],
"height": 1024,
"metadata": {
"name": "slate",
"license": "SIL OFL 1.1"
},
"preferences": {
"showGlyphs": true,
"showQuickUse": true,
"showQuickUse2": true,
"showSVGs": true,
"fontPref": {
"prefix": "icon-",
"metadata": {
"fontFamily": "slate",
"majorVersion": 1,
"minorVersion": 0,
"description": "Based on FontAwesome",
"license": "SIL OFL 1.1"
},
"metrics": {
"emSize": 1024,
"baseline": 6.25,
"whitespace": 50
},
"resetPoint": 58880,
"showSelector": false,
"selector": "class",
"classSelector": ".icon",
"showMetrics": false,
"showMetadata": true,
"showVersion": true,
"ie7": false
},
"imagePref": {
"prefix": "icon-",
"png": true,
"useClassSelector": true,
"color": 4473924,
"bgColor": 16777215
},
"historySize": 100,
"showCodes": true,
"gridSize": 16,
"showLiga": false
}
}

View File

@ -1,95 +0,0 @@
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
# this is based on https://github.com/rouge-ruby/rouge/blob/master/lib/rouge/themes/monokai_sublime.rb
# but without the added background, and changed styling for JSON keys to be soft_yellow instead of white
module Rouge
module Themes
class MonokaiSublimeSlate < CSSTheme
name 'monokai.sublime.slate'
palette :black => '#000000'
palette :bright_green => '#a6e22e'
palette :bright_pink => '#f92672'
palette :carmine => '#960050'
palette :dark => '#49483e'
palette :dark_grey => '#888888'
palette :dark_red => '#aa0000'
palette :dimgrey => '#75715e'
palette :emperor => '#555555'
palette :grey => '#999999'
palette :light_grey => '#aaaaaa'
palette :light_violet => '#ae81ff'
palette :soft_cyan => '#66d9ef'
palette :soft_yellow => '#e6db74'
palette :very_dark => '#1e0010'
palette :whitish => '#f8f8f2'
palette :orange => '#f6aa11'
palette :white => '#ffffff'
style Generic::Heading, :fg => :grey
style Literal::String::Regex, :fg => :orange
style Generic::Output, :fg => :dark_grey
style Generic::Prompt, :fg => :emperor
style Generic::Strong, :bold => false
style Generic::Subheading, :fg => :light_grey
style Name::Builtin, :fg => :orange
style Comment::Multiline,
Comment::Preproc,
Comment::Single,
Comment::Special,
Comment, :fg => :dimgrey
style Error,
Generic::Error,
Generic::Traceback, :fg => :carmine
style Generic::Deleted,
Generic::Inserted,
Generic::Emph, :fg => :dark
style Keyword::Constant,
Keyword::Declaration,
Keyword::Reserved,
Name::Constant,
Keyword::Type, :fg => :soft_cyan
style Literal::Number::Float,
Literal::Number::Hex,
Literal::Number::Integer::Long,
Literal::Number::Integer,
Literal::Number::Oct,
Literal::Number,
Literal::String::Char,
Literal::String::Escape,
Literal::String::Symbol, :fg => :light_violet
style Literal::String::Doc,
Literal::String::Double,
Literal::String::Backtick,
Literal::String::Heredoc,
Literal::String::Interpol,
Literal::String::Other,
Literal::String::Single,
Literal::String, :fg => :soft_yellow
style Name::Attribute,
Name::Class,
Name::Decorator,
Name::Exception,
Name::Function, :fg => :bright_green
style Name::Variable::Class,
Name::Namespace,
Name::Entity,
Name::Builtin::Pseudo,
Name::Variable::Global,
Name::Variable::Instance,
Name::Variable,
Text::Whitespace,
Text,
Name, :fg => :white
style Name::Label, :fg => :bright_pink
style Operator::Word,
Name::Tag,
Keyword,
Keyword::Namespace,
Keyword::Pseudo,
Operator, :fg => :bright_pink
end
end
end

View File

@ -1,16 +0,0 @@
module Multilang
def block_code(code, full_lang_name)
if full_lang_name
parts = full_lang_name.split('--')
rouge_lang_name = (parts) ? parts[0] : "" # just parts[0] here causes null ref exception when no language specified
super(code, rouge_lang_name).sub("highlight #{rouge_lang_name}") do |match|
match + " tab-" + full_lang_name
end
else
super(code, full_lang_name)
end
end
end
require 'middleman-core/renderers/redcarpet'
Middleman::Renderers::MiddlemanRedcarpetHTML.send :include, Multilang

View File

@ -1,22 +0,0 @@
# Nested unique header generation
require 'middleman-core/renderers/redcarpet'
class NestingUniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
def initialize
super
@@headers_history = {} if !defined?(@@headers_history)
end
def header(text, header_level)
friendly_text = text.gsub(/<[^>]*>/,"").parameterize
@@headers_history[header_level] = text.parameterize
if header_level > 1
for i in (header_level - 1).downto(1)
friendly_text.prepend("#{@@headers_history[i]}-") if @@headers_history.key?(i)
end
end
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>"
end
end

View File

@ -1,31 +0,0 @@
require 'nokogiri'
def toc_data(page_content)
html_doc = Nokogiri::HTML::DocumentFragment.parse(page_content)
# get a flat list of headers
headers = []
html_doc.css('h1, h2, h3').each do |header|
headers.push({
id: header.attribute('id').to_s,
content: header.children,
title: header.children.to_s.gsub(/<[^>]*>/, ''),
level: header.name[1].to_i,
children: []
})
end
[3,2].each do |header_level|
header_to_nest = nil
headers = headers.reject do |header|
if header[:level] == header_level
header_to_nest[:children].push header if header_to_nest
true
else
header_to_nest = header if header[:level] < header_level
false
end
end
end
headers
end

View File

@ -1,24 +0,0 @@
# Unique header generation
require 'middleman-core/renderers/redcarpet'
require 'digest'
class UniqueHeadCounter < Middleman::Renderers::MiddlemanRedcarpetHTML
def initialize
super
@head_count = {}
end
def header(text, header_level)
friendly_text = text.gsub(/<[^>]*>/,"").parameterize
if friendly_text.strip.length == 0
# Looks like parameterize removed the whole thing! It removes many unicode
# characters like Chinese and Russian. To get a unique URL, let's just
# URI escape the whole header
friendly_text = Digest::SHA1.hexdigest(text)[0,10]
end
@head_count[friendly_text] ||= 0
@head_count[friendly_text] += 1
if @head_count[friendly_text] > 1
friendly_text += "-#{@head_count[friendly_text]}"
end
return "<h#{header_level} id='#{friendly_text}'>#{text}</h#{header_level}>"
end
end

View File

@ -1,248 +0,0 @@
#!/usr/bin/env bash
set -o errexit #abort if any command fails
me=$(basename "$0")
help_message="\
Usage: $me [<options>] <command> [<command-options>]
Run commands related to the slate process.
Commands:
serve Run the middleman server process, useful for
development.
build Run the build process.
deploy Will build and deploy files to branch. Use
--no-build to only deploy.
Global Options:
-h, --help Show this help information.
-v, --verbose Increase verbosity. Useful for debugging.
Deploy options:
-e, --allow-empty Allow deployment of an empty directory.
-m, --message MESSAGE Specify the message used when committing on the
deploy branch.
-n, --no-hash Don't append the source commit's hash to the deploy
commit's message.
--no-build Do not build the source files.
"
run_serve() {
exec bundle exec middleman serve --watcher-force-polling
}
run_build() {
bundle exec middleman build --clean
}
parse_args() {
# Set args from a local environment file.
if [ -e ".env" ]; then
source .env
fi
command=
# Parse arg flags
# If something is exposed as an environment variable, set/overwrite it
# here. Otherwise, set/overwrite the internal variable instead.
while : ; do
if [[ $1 = "-h" || $1 = "--help" ]]; then
echo "$help_message"
exit 0
elif [[ $1 = "-v" || $1 = "--verbose" ]]; then
verbose=true
shift
elif [[ $1 = "-e" || $1 = "--allow-empty" ]]; then
allow_empty=true
shift
elif [[ ( $1 = "-m" || $1 = "--message" ) && -n $2 ]]; then
commit_message=$2
shift 2
elif [[ $1 = "-n" || $1 = "--no-hash" ]]; then
GIT_DEPLOY_APPEND_HASH=false
shift
elif [[ $1 = "--no-build" ]]; then
no_build=true
shift
elif [[ $1 = "serve" || $1 = "build" || $1 = "deploy" ]]; then
if [ ! -z "${command}" ]; then
>&2 echo "You can only specify one command."
exit 1
fi
command=$1
shift
elif [ -z $1 ]; then
break
fi
done
if [ -z "${command}" ]; then
>&2 echo "Command not specified."
exit 1
fi
# Set internal option vars from the environment and arg flags. All internal
# vars should be declared here, with sane defaults if applicable.
# Source directory & target branch.
deploy_directory=build
deploy_branch=gh-pages
#if no user identity is already set in the current git environment, use this:
default_username=${GIT_DEPLOY_USERNAME:-deploy.sh}
default_email=${GIT_DEPLOY_EMAIL:-}
#repository to deploy to. must be readable and writable.
repo=origin
#append commit hash to the end of message by default
append_hash=${GIT_DEPLOY_APPEND_HASH:-true}
}
main() {
enable_expanded_output
if ! git diff --exit-code --quiet --cached; then
echo Aborting due to uncommitted changes in the index >&2
return 1
fi
commit_title=`git log -n 1 --format="%s" HEAD`
commit_hash=` git log -n 1 --format="%H" HEAD`
#default commit message uses last title if a custom one is not supplied
if [[ -z $commit_message ]]; then
commit_message="publish: $commit_title"
fi
#append hash to commit message unless no hash flag was found
if [ $append_hash = true ]; then
commit_message="$commit_message"$'\n\n'"generated from commit $commit_hash"
fi
previous_branch=`git rev-parse --abbrev-ref HEAD`
if [ ! -d "$deploy_directory" ]; then
echo "Deploy directory '$deploy_directory' does not exist. Aborting." >&2
return 1
fi
# must use short form of flag in ls for compatibility with macOS and BSD
if [[ -z `ls -A "$deploy_directory" 2> /dev/null` && -z $allow_empty ]]; then
echo "Deploy directory '$deploy_directory' is empty. Aborting. If you're sure you want to deploy an empty tree, use the --allow-empty / -e flag." >&2
return 1
fi
if git ls-remote --exit-code $repo "refs/heads/$deploy_branch" ; then
# deploy_branch exists in $repo; make sure we have the latest version
disable_expanded_output
git fetch --force $repo $deploy_branch:$deploy_branch
enable_expanded_output
fi
# check if deploy_branch exists locally
if git show-ref --verify --quiet "refs/heads/$deploy_branch"
then incremental_deploy
else initial_deploy
fi
restore_head
}
initial_deploy() {
git --work-tree "$deploy_directory" checkout --orphan $deploy_branch
git --work-tree "$deploy_directory" add --all
commit+push
}
incremental_deploy() {
#make deploy_branch the current branch
git symbolic-ref HEAD refs/heads/$deploy_branch
#put the previously committed contents of deploy_branch into the index
git --work-tree "$deploy_directory" reset --mixed --quiet
git --work-tree "$deploy_directory" add --all
set +o errexit
diff=$(git --work-tree "$deploy_directory" diff --exit-code --quiet HEAD --)$?
set -o errexit
case $diff in
0) echo No changes to files in $deploy_directory. Skipping commit.;;
1) commit+push;;
*)
echo git diff exited with code $diff. Aborting. Staying on branch $deploy_branch so you can debug. To switch back to main, use: git symbolic-ref HEAD refs/heads/main && git reset --mixed >&2
return $diff
;;
esac
}
commit+push() {
set_user_id
git --work-tree "$deploy_directory" commit -m "$commit_message"
disable_expanded_output
#--quiet is important here to avoid outputting the repo URL, which may contain a secret token
git push --quiet $repo $deploy_branch
enable_expanded_output
}
#echo expanded commands as they are executed (for debugging)
enable_expanded_output() {
if [ $verbose ]; then
set -o xtrace
set +o verbose
fi
}
#this is used to avoid outputting the repo URL, which may contain a secret token
disable_expanded_output() {
if [ $verbose ]; then
set +o xtrace
set -o verbose
fi
}
set_user_id() {
if [[ -z `git config user.name` ]]; then
git config user.name "$default_username"
fi
if [[ -z `git config user.email` ]]; then
git config user.email "$default_email"
fi
}
restore_head() {
if [[ $previous_branch = "HEAD" ]]; then
#we weren't on any branch before, so just set HEAD back to the commit it was on
git update-ref --no-deref HEAD $commit_hash $deploy_branch
else
git symbolic-ref HEAD refs/heads/$previous_branch
fi
git reset --mixed
}
filter() {
sed -e "s|$repo|\$repo|g"
}
sanitize() {
"$@" 2> >(filter 1>&2) | filter
}
parse_args "$@"
if [ "${command}" = "serve" ]; then
run_serve
elif [[ "${command}" = "build" ]]; then
run_build
elif [[ ${command} = "deploy" ]]; then
if [[ ${no_build} != true ]]; then
run_build
fi
main "$@"
fi

View File

@ -1,14 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="slate" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" d="" horiz-adv-x="512" />
<glyph unicode="&#xe600;" d="M438.857 877.714q119.429 0 220.286-58.857t159.714-159.714 58.857-220.286-58.857-220.286-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857zM512 165.143v108.571q0 8-5.143 13.429t-12.571 5.429h-109.714q-7.429 0-13.143-5.714t-5.714-13.143v-108.571q0-7.429 5.714-13.143t13.143-5.714h109.714q7.429 0 12.571 5.429t5.143 13.429zM510.857 361.714l10.286 354.857q0 6.857-5.714 10.286-5.714 4.571-13.714 4.571h-125.714q-8 0-13.714-4.571-5.714-3.429-5.714-10.286l9.714-354.857q0-5.714 5.714-10t13.714-4.286h105.714q8 0 13.429 4.286t6 10z" />
<glyph unicode="&#xe602;" d="M585.143 164.571v91.429q0 8-5.143 13.143t-13.143 5.143h-54.857v292.571q0 8-5.143 13.143t-13.143 5.143h-182.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h54.857v-182.857h-54.857q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h256q8 0 13.143 5.143t5.143 13.143zM512 676.571v91.429q0 8-5.143 13.143t-13.143 5.143h-109.714q-8 0-13.143-5.143t-5.143-13.143v-91.429q0-8 5.143-13.143t13.143-5.143h109.714q8 0 13.143 5.143t5.143 13.143zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
<glyph unicode="&#xe606;" d="M733.714 531.428q0 16-10.286 26.286l-52 51.429q-10.857 10.857-25.714 10.857t-25.714-10.857l-233.143-232.571-129.143 129.143q-10.857 10.857-25.714 10.857t-25.714-10.857l-52-51.429q-10.286-10.286-10.286-26.286 0-15.429 10.286-25.714l206.857-206.857q10.857-10.857 25.714-10.857 15.429 0 26.286 10.857l310.286 310.286q10.286 10.286 10.286 25.714zM877.714 438.857q0-119.429-58.857-220.286t-159.714-159.714-220.286-58.857-220.286 58.857-159.714 159.714-58.857 220.286 58.857 220.286 159.714 159.714 220.286 58.857 220.286-58.857 159.714-159.714 58.857-220.286z" />
<glyph unicode="&#xe607;" d="M658.286 475.428q0 105.714-75.143 180.857t-180.857 75.143-180.857-75.143-75.143-180.857 75.143-180.857 180.857-75.143 180.857 75.143 75.143 180.857zM950.857 0q0-29.714-21.714-51.429t-51.429-21.714q-30.857 0-51.429 21.714l-196 195.429q-102.286-70.857-228-70.857-81.714 0-156.286 31.714t-128.571 85.714-85.714 128.571-31.714 156.286 31.714 156.286 85.714 128.571 128.571 85.714 156.286 31.714 156.286-31.714 128.571-85.714 85.714-128.571 31.714-156.286q0-125.714-70.857-228l196-196q21.143-21.143 21.143-51.429z" horiz-adv-x="951" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

View File

@ -1,39 +0,0 @@
# Authentication
> To authorize, use this code:
```ruby
require 'kittn'
api = Kittn::APIClient.authorize!('meowmeowmeow')
```
```python
import kittn
api = kittn.authorize('meowmeowmeow')
```
```shell
# With shell, you can just pass the correct header with each request
curl "api_endpoint_here" \
-H "Authorization: meowmeowmeow"
```
```javascript
const kittn = require('kittn');
let api = kittn.authorize('meowmeowmeow');
```
> Make sure to replace `meowmeowmeow` with your API key.
Kittn uses API keys to allow access to the API. You can register a new Kittn API key at our [developer portal](http://example.com/developers).
Kittn expects for the API key to be included in all API requests to the server in a header that looks like the following:
`Authorization: meowmeowmeow`
<aside class="notice">
You must replace <code>meowmeowmeow</code> with your personal API key.
</aside>

View File

@ -1,22 +0,0 @@
# Errors
<aside class="notice">
This error section is stored in a separate file in <code>includes/_errors.md</code>. Slate allows you to optionally separate out your docs into many files...just save them to the <code>includes</code> folder and add them to the top of your <code>index.md</code>'s frontmatter. Files are included in the order listed.
</aside>
The Kittn API uses the following error codes:
Error Code | Meaning
---------- | -------
400 | Bad Request -- Your request is invalid.
401 | Unauthorized -- Your API key is wrong.
403 | Forbidden -- The kitten requested is hidden for administrators only.
404 | Not Found -- The specified kitten could not be found.
405 | Method Not Allowed -- You tried to access a kitten with an invalid method.
406 | Not Acceptable -- You requested a format that isn't json.
410 | Gone -- The kitten requested has been removed from our servers.
418 | I'm a teapot.
429 | Too Many Requests -- You're requesting too many kittens! Slow down!
500 | Internal Server Error -- We had a problem with our server. Try again later.
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later.

View File

@ -1,47 +0,0 @@
# Gitignores
## gitignore模板列表
获取gitignore模板列表, 支持名称搜索过滤
> 示例:
```shell
curl -X GET \
-d "name=Ada" \
http://localhost:3000/api/ignores.json
```
```javascript
await octokit.request('GET /api/ignores.json')
```
### HTTP 请求
`GET api/ignores.json`
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
name |否| 否 ||string |gitignore名称
### 返回字段说明
参数 | 类型 | 字段说明
--------- | ----------- | -----------
id |int |id |
name |string|gitignore名称|
> 返回的JSON示例:
```json
{
"ignores": [
{
"id": 1,
"name": "Ada"
}
]
}
```
<aside class="success">
Success — a happy kitten is an authenticated kitten!
</aside>

View File

@ -1 +0,0 @@
# Issues

View File

@ -1,57 +0,0 @@
# Licenses
## Get All Licenses
The Licenses API returns metadata about popular open source licenses and information about a particular project's license file.
> 示例:
```shell
curl -X GET \
-d "name=AFL" \
http://localhost:3000/api/licenses
```
```javascript
await octokit.request('GET /api/licenses')
```
### HTTP Request
`GET https://forgeplus.trustie.net/api/licenses.json`
### 请求参数
Name | Required | Type | Description
----- | ---- | ----- | -----
name |false|string |name of the license
> 返回字段说明:
```json
{
"licenses": [
{
"id": 57,
"name": "AFL-1.2"
},
{
"id": 76,
"name": "AFL-3.0"
},
{
"id": 214,
"name": "AFL-1.1"
},
{
"id": 326,
"name": "AFL-2.1"
},
{
"id": 350,
"name": "AFL-2.0"
}
]
}
```

View File

@ -1 +0,0 @@
# Organizations

View File

@ -280,7 +280,7 @@ repo |是| |string |项目标识identifier
### 返回字段说明
参数 | 类型 | 字段说明
--------- | ----------- | -----------
menu_name |string|导航名称, home:主页,code:代码库,issues:修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
menu_name |string|导航名称, home:主页,code:代码库,issues:修,pulls:合并请求,devops:工作流,versions:里程碑,activity:动态,setting:仓库设置
> 返回的JSON示例:
@ -408,7 +408,7 @@ await octokit.request('POST /api/yystopf/ceshi/project_units')
### 请求参数
参数 | 必选 | 默认 | 类型 | 字段说明
--------- | ------- | ------- | -------- | ----------
|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:修,pulls:合并请求,devops:工作流,versions:里程碑 |
|unit_types |是| |array | 项目模块内容, 支持以下参数:code:代码库,issues:修,pulls:合并请求,devops:工作流,versions:里程碑 |
### 返回字段说明:

View File

@ -1240,11 +1240,11 @@ await octokit.request('GET /api/yystopf/ceshi/webhooks/3/edit.json')
|delete|分支或标签删除|
|fork|仓库被fork|
|push|git仓库推送|
|issue|修已打开、已关闭、已重新打开或编辑|
|issue_assign|修被指派|
|issue_label|修标签被更新或删除|
|issue_milestone|修被收入里程碑|
|issue_comment|修评论|
|issue|修已打开、已关闭、已重新打开或编辑|
|issue_assign|修被指派|
|issue_label|修标签被更新或删除|
|issue_milestone|修被收入里程碑|
|issue_comment|修评论|
|pull_request|合并请求|
|pull_request_assign|合并请求被指派|
|pull_request_label|合并请求被贴上标签|
@ -1337,11 +1337,11 @@ await octokit.request('POST /api/yystopf/ceshi/webhooks.json')
|delete|分支或标签删除|
|fork|仓库被fork|
|push|git仓库推送|
|issue|修已打开、已关闭、已重新打开或编辑|
|issue_assign|修被指派|
|issue_label|修标签被更新或删除|
|issue_milestone|修被收入里程碑|
|issue_comment|修评论|
|issue|修已打开、已关闭、已重新打开或编辑|
|issue_assign|修被指派|
|issue_label|修标签被更新或删除|
|issue_milestone|修被收入里程碑|
|issue_comment|修评论|
|pull_request|合并请求|
|pull_request_assign|合并请求被指派|
|pull_request_label|合并请求被贴上标签|
@ -1440,11 +1440,11 @@ await octokit.request('PATCH /api/yystopf/ceshi/webhooks/7.json')
|delete|分支或标签删除|
|fork|仓库被fork|
|push|git仓库推送|
|issue|修已打开、已关闭、已重新打开或编辑|
|issue_assign|修被指派|
|issue_label|修标签被更新或删除|
|issue_milestone|修被收入里程碑|
|issue_comment|修评论|
|issue|修已打开、已关闭、已重新打开或编辑|
|issue_assign|修被指派|
|issue_label|修标签被更新或删除|
|issue_milestone|修被收入里程碑|
|issue_comment|修评论|
|pull_request|合并请求|
|pull_request_assign|合并请求被指派|
|pull_request_label|合并请求被贴上标签|

View File

@ -1 +0,0 @@
# Teams

View File

@ -90,13 +90,13 @@ await octokit.request('GET /api/users/:login/messages.json')
#### 消息来源source字段说明
类型|说明
--------- | -----------
|IssueAssigned | 有新指派给我的修 |
|IssueAssignerExpire | 我负责的修截止日期到达最后一天 |
|IssueAtme | 在修中@我 |
|IssueChanged | 我创建或负责的修状态变更 |
|IssueCreatorExpire | 我创建的修截止日期到达最后一天 |
|IssueDeleted | 我创建或负责的修删除 |
|IssueJournal | 我创建或负责的修有新的评论 |
|IssueAssigned | 有新指派给我的修 |
|IssueAssignerExpire | 我负责的修截止日期到达最后一天 |
|IssueAtme | 在修中@我 |
|IssueChanged | 我创建或负责的修状态变更 |
|IssueCreatorExpire | 我创建的修截止日期到达最后一天 |
|IssueDeleted | 我创建或负责的修删除 |
|IssueJournal | 我创建或负责的修有新的评论 |
|LoginIpTip | 登录异常提示 |
|OrganizationJoined | 账号被拉入组织 |
|OrganizationLeft | 账号被移出组织 |
@ -104,7 +104,7 @@ await octokit.request('GET /api/users/:login/messages.json')
|ProjectDeleted | 我关注的仓库被删除 |
|ProjectFollowed | 我管理的仓库被关注 |
|ProjectForked | 我管理的仓库被复刻 |
|ProjectIssue | 我管理/关注的仓库有新的修 |
|ProjectIssue | 我管理/关注的仓库有新的修 |
|ProjectJoined | 账号被拉入项目 |
|ProjectLeft | 账号被移出项目 |
|ProjectMemberJoined | 我管理的仓库有成员加入 |
@ -250,7 +250,7 @@ await octokit.request('POST /api/users/:login/messages.json')
--------- | ----------- | -----------
|type | string | 消息类型 |
|receivers_login | array | 需要发送消息的用户名数组|
|atmeable_type | string | atme消息对象是从哪里@我的比如评论Journal、Issue、合并请求PullRequest |
|atmeable_type | string | atme消息对象是从哪里@我的比如评论Journal、Issue、合并请求PullRequest |
|atmeable_id | integer | atme消息对象id |
> 请求的JSON示例:
@ -469,7 +469,7 @@ await octokit.request('GET /api/template_message_settings.json')
"total_settings_count": 4,
"settings": [
{
"name": "修被指派",
"name": "修被指派",
"key": "IssueAssigned",
"notification_disabled": true,
"email_disabled": false
@ -488,7 +488,7 @@ await octokit.request('GET /api/template_message_settings.json')
"total_settings_count": 4,
"settings": [
{
"name": "有新的修",
"name": "有新的修",
"key": "Issue",
"notification_disabled": true,
"email_disabled": false
@ -875,7 +875,7 @@ await octokit.request('GET /api/users/:login/statistics/activity.json')
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|dates |array |时间 |
|issues_count |array |修数量|
|issues_count |array |修数量|
|pull_requests_count |array |合并请求数量|
|commtis_count |array |贡献数量|
@ -1084,7 +1084,7 @@ await octokit.request('GET /api/users/:login/project_trends.json')
参数 | 类型 | 字段说明
--------- | ----------- | -----------
|total_count |int |所选时间内的总动态数 |
|project_trends.trend_type |string|动态类型IssueVersionRelease版本发布PullRequest合并请求|
|project_trends.trend_type |string|动态类型IssueVersionRelease版本发布PullRequest合并请求|
|project_trends.action_type |string|操作类型|
|project_trends.trend_id |integer|动态id|
|project_trends.user_name |string|用户名称|

View File

@ -1,2 +0,0 @@
//= require ./all_nosearch
//= require ./app/_search

View File

@ -1,27 +0,0 @@
//= require ./lib/_energize
//= require ./app/_copy
//= require ./app/_toc
//= require ./app/_lang
function adjustLanguageSelectorWidth() {
const elem = $('.dark-box > .lang-selector');
elem.width(elem.parent().width());
}
$(function() {
loadToc($('#toc'), '.toc-link', '.toc-list-h2', 10);
setupLanguages($('body').data('languages'));
$('.content').imagesLoaded( function() {
window.recacheHeights();
window.refreshToc();
});
$(window).resize(function() {
adjustLanguageSelectorWidth();
});
adjustLanguageSelectorWidth();
});
window.onpopstate = function() {
activateLanguage(getLanguageFromQueryString());
};

View File

@ -1,15 +0,0 @@
function copyToClipboard(container) {
const el = document.createElement('textarea');
el.value = container.textContent.replace(/\n$/, '');
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.body.removeChild(el);
}
function setupCodeCopy() {
$('pre.highlight').prepend('<div class="copy-clipboard"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><title>Copy to Clipboard</title><path d="M18 6v-6h-18v18h6v6h18v-18h-6zm-12 10h-4v-14h14v4h-10v10zm16 6h-14v-14h14v14z"></path></svg></div>');
$('.copy-clipboard').on('click', function() {
copyToClipboard(this.parentNode.children[1]);
});
}

View File

@ -1,164 +0,0 @@
//= require ../lib/_jquery
/*
Copyright 2008-2013 Concur Technologies, Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
*/
;(function () {
'use strict';
var languages = [];
window.setupLanguages = setupLanguages;
window.activateLanguage = activateLanguage;
window.getLanguageFromQueryString = getLanguageFromQueryString;
function activateLanguage(language) {
if (!language) return;
if (language === "") return;
$(".lang-selector a").removeClass('active');
$(".lang-selector a[data-language-name='" + language + "']").addClass('active');
for (var i=0; i < languages.length; i++) {
$(".highlight.tab-" + languages[i]).hide();
$(".lang-specific." + languages[i]).hide();
}
$(".highlight.tab-" + language).show();
$(".lang-specific." + language).show();
window.recacheHeights();
// scroll to the new location of the position
if ($(window.location.hash).get(0)) {
$(window.location.hash).get(0).scrollIntoView(true);
}
}
// parseURL and stringifyURL are from https://github.com/sindresorhus/query-string
// MIT licensed
// https://github.com/sindresorhus/query-string/blob/7bee64c16f2da1a326579e96977b9227bf6da9e6/license
function parseURL(str) {
if (typeof str !== 'string') {
return {};
}
str = str.trim().replace(/^(\?|#|&)/, '');
if (!str) {
return {};
}
return str.split('&').reduce(function (ret, param) {
var parts = param.replace(/\+/g, ' ').split('=');
var key = parts[0];
var val = parts[1];
key = decodeURIComponent(key);
// missing `=` should be `null`:
// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
val = val === undefined ? null : decodeURIComponent(val);
if (!ret.hasOwnProperty(key)) {
ret[key] = val;
} else if (Array.isArray(ret[key])) {
ret[key].push(val);
} else {
ret[key] = [ret[key], val];
}
return ret;
}, {});
};
function stringifyURL(obj) {
return obj ? Object.keys(obj).sort().map(function (key) {
var val = obj[key];
if (Array.isArray(val)) {
return val.sort().map(function (val2) {
return encodeURIComponent(key) + '=' + encodeURIComponent(val2);
}).join('&');
}
return encodeURIComponent(key) + '=' + encodeURIComponent(val);
}).join('&') : '';
};
// gets the language set in the query string
function getLanguageFromQueryString() {
if (location.search.length >= 1) {
var language = parseURL(location.search).language;
if (language) {
return language;
} else if (jQuery.inArray(location.search.substr(1), languages) != -1) {
return location.search.substr(1);
}
}
return false;
}
// returns a new query string with the new language in it
function generateNewQueryString(language) {
var url = parseURL(location.search);
if (url.language) {
url.language = language;
return stringifyURL(url);
}
return language;
}
// if a button is clicked, add the state to the history
function pushURL(language) {
if (!history) { return; }
var hash = window.location.hash;
if (hash) {
hash = hash.replace(/^#+/, '');
}
history.pushState({}, '', '?' + generateNewQueryString(language) + '#' + hash);
// save language as next default
localStorage.setItem("language", language);
}
function setupLanguages(l) {
var defaultLanguage = localStorage.getItem("language");
languages = l;
var presetLanguage = getLanguageFromQueryString();
if (presetLanguage) {
// the language is in the URL, so use that language!
activateLanguage(presetLanguage);
localStorage.setItem("language", presetLanguage);
} else if ((defaultLanguage !== null) && (jQuery.inArray(defaultLanguage, languages) != -1)) {
// the language was the last selected one saved in localstorage, so use that language!
activateLanguage(defaultLanguage);
} else {
// no language selected, so use the default
activateLanguage(languages[0]);
}
}
// if we click on a language tab, activate that language
$(function() {
$(".lang-selector a").on("click", function() {
var language = $(this).data("language-name");
pushURL(language);
activateLanguage(language);
return false;
});
});
})();

View File

@ -1,102 +0,0 @@
//= require ../lib/_lunr
//= require ../lib/_jquery
//= require ../lib/_jquery.highlight
;(function () {
'use strict';
var content, searchResults;
var highlightOpts = { element: 'span', className: 'search-highlight' };
var searchDelay = 0;
var timeoutHandle = 0;
var index;
function populate() {
index = lunr(function(){
this.ref('id');
this.field('title', { boost: 10 });
this.field('body');
this.pipeline.add(lunr.trimmer, lunr.stopWordFilter);
var lunrConfig = this;
$('h1, h2').each(function() {
var title = $(this);
var body = title.nextUntil('h1, h2');
lunrConfig.add({
id: title.prop('id'),
title: title.text(),
body: body.text()
});
});
});
determineSearchDelay();
}
$(populate);
$(bind);
function determineSearchDelay() {
if (index.tokenSet.toArray().length>5000) {
searchDelay = 300;
}
}
function bind() {
content = $('.content');
searchResults = $('.search-results');
$('#input-search').on('keyup',function(e) {
var wait = function() {
return function(executingFunction, waitTime){
clearTimeout(timeoutHandle);
timeoutHandle = setTimeout(executingFunction, waitTime);
};
}();
wait(function(){
search(e);
}, searchDelay);
});
}
function search(event) {
var searchInput = $('#input-search')[0];
unhighlight();
searchResults.addClass('visible');
// ESC clears the field
if (event.keyCode === 27) searchInput.value = '';
if (searchInput.value) {
var results = index.search(searchInput.value).filter(function(r) {
return r.score > 0.0001;
});
if (results.length) {
searchResults.empty();
$.each(results, function (index, result) {
var elem = document.getElementById(result.ref);
searchResults.append("<li><a href='#" + result.ref + "'>" + $(elem).text() + "</a></li>");
});
highlight.call(searchInput);
} else {
searchResults.html('<li></li>');
$('.search-results li').text('No Results Found for "' + searchInput.value + '"');
}
} else {
unhighlight();
searchResults.removeClass('visible');
}
}
function highlight() {
if (this.value) content.highlight(this.value, highlightOpts);
}
function unhighlight() {
content.unhighlight(highlightOpts);
}
})();

View File

@ -1,122 +0,0 @@
//= require ../lib/_jquery
//= require ../lib/_imagesloaded.min
;(function () {
'use strict';
var htmlPattern = /<[^>]*>/g;
var loaded = false;
var debounce = function(func, waitTime) {
var timeout = false;
return function() {
if (timeout === false) {
setTimeout(function() {
func();
timeout = false;
}, waitTime);
timeout = true;
}
};
};
var closeToc = function() {
$(".toc-wrapper").removeClass('open');
$("#nav-button").removeClass('open');
};
function loadToc($toc, tocLinkSelector, tocListSelector, scrollOffset) {
var headerHeights = {};
var pageHeight = 0;
var windowHeight = 0;
var originalTitle = document.title;
var recacheHeights = function() {
headerHeights = {};
pageHeight = $(document).height();
windowHeight = $(window).height();
$toc.find(tocLinkSelector).each(function() {
var targetId = $(this).attr('href');
if (targetId[0] === "#") {
headerHeights[targetId] = $("#" + $.escapeSelector(targetId.substring(1))).offset().top;
}
});
};
var refreshToc = function() {
var currentTop = $(document).scrollTop() + scrollOffset;
if (currentTop + windowHeight >= pageHeight) {
// at bottom of page, so just select last header by making currentTop very large
// this fixes the problem where the last header won't ever show as active if its content
// is shorter than the window height
currentTop = pageHeight + 1000;
}
var best = null;
for (var name in headerHeights) {
if ((headerHeights[name] < currentTop && headerHeights[name] > headerHeights[best]) || best === null) {
best = name;
}
}
// Catch the initial load case
if (currentTop == scrollOffset && !loaded) {
best = window.location.hash;
loaded = true;
}
var $best = $toc.find("[href='" + best + "']").first();
if (!$best.hasClass("active")) {
// .active is applied to the ToC link we're currently on, and its parent <ul>s selected by tocListSelector
// .active-expanded is applied to the ToC links that are parents of this one
$toc.find(".active").removeClass("active");
$toc.find(".active-parent").removeClass("active-parent");
$best.addClass("active");
$best.parents(tocListSelector).addClass("active").siblings(tocLinkSelector).addClass('active-parent');
$best.siblings(tocListSelector).addClass("active");
$toc.find(tocListSelector).filter(":not(.active)").slideUp(150);
$toc.find(tocListSelector).filter(".active").slideDown(150);
if (window.history.replaceState) {
window.history.replaceState(null, "", best);
}
var thisTitle = $best.data("title");
if (thisTitle !== undefined && thisTitle.length > 0) {
document.title = thisTitle.replace(htmlPattern, "") + " " + originalTitle;
} else {
document.title = originalTitle;
}
}
};
var makeToc = function() {
recacheHeights();
refreshToc();
$("#nav-button").click(function() {
$(".toc-wrapper").toggleClass('open');
$("#nav-button").toggleClass('open');
return false;
});
$(".page-wrapper").click(closeToc);
$(".toc-link").click(closeToc);
// reload immediately after scrolling on toc click
$toc.find(tocLinkSelector).click(function() {
setTimeout(function() {
refreshToc();
}, 0);
});
$(window).scroll(debounce(refreshToc, 200));
$(window).resize(debounce(recacheHeights, 200));
};
makeToc();
window.recacheHeights = recacheHeights;
window.refreshToc = refreshToc;
}
window.loadToc = loadToc;
})();

View File

@ -1,169 +0,0 @@
/**
* energize.js v0.1.0
*
* Speeds up click events on mobile devices.
* https://github.com/davidcalhoun/energize.js
*/
(function() { // Sandbox
/**
* Don't add to non-touch devices, which don't need to be sped up
*/
if(!('ontouchstart' in window)) return;
var lastClick = {},
isThresholdReached, touchstart, touchmove, touchend,
click, closest;
/**
* isThresholdReached
*
* Compare touchstart with touchend xy coordinates,
* and only fire simulated click event if the coordinates
* are nearby. (don't want clicking to be confused with a swipe)
*/
isThresholdReached = function(startXY, xy) {
return Math.abs(startXY[0] - xy[0]) > 5 || Math.abs(startXY[1] - xy[1]) > 5;
};
/**
* touchstart
*
* Save xy coordinates when the user starts touching the screen
*/
touchstart = function(e) {
this.startXY = [e.touches[0].clientX, e.touches[0].clientY];
this.threshold = false;
};
/**
* touchmove
*
* Check if the user is scrolling past the threshold.
* Have to check here because touchend will not always fire
* on some tested devices (Kindle Fire?)
*/
touchmove = function(e) {
// NOOP if the threshold has already been reached
if(this.threshold) return false;
this.threshold = isThresholdReached(this.startXY, [e.touches[0].clientX, e.touches[0].clientY]);
};
/**
* touchend
*
* If the user didn't scroll past the threshold between
* touchstart and touchend, fire a simulated click.
*
* (This will fire before a native click)
*/
touchend = function(e) {
// Don't fire a click if the user scrolled past the threshold
if(this.threshold || isThresholdReached(this.startXY, [e.changedTouches[0].clientX, e.changedTouches[0].clientY])) {
return;
}
/**
* Create and fire a click event on the target element
* https://developer.mozilla.org/en/DOM/event.initMouseEvent
*/
var touch = e.changedTouches[0],
evt = document.createEvent('MouseEvents');
evt.initMouseEvent('click', true, true, window, 0, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
evt.simulated = true; // distinguish from a normal (nonsimulated) click
e.target.dispatchEvent(evt);
};
/**
* click
*
* Because we've already fired a click event in touchend,
* we need to listed for all native click events here
* and suppress them as necessary.
*/
click = function(e) {
/**
* Prevent ghost clicks by only allowing clicks we created
* in the click event we fired (look for e.simulated)
*/
var time = Date.now(),
timeDiff = time - lastClick.time,
x = e.clientX,
y = e.clientY,
xyDiff = [Math.abs(lastClick.x - x), Math.abs(lastClick.y - y)],
target = closest(e.target, 'A') || e.target, // needed for standalone apps
nodeName = target.nodeName,
isLink = nodeName === 'A',
standAlone = window.navigator.standalone && isLink && e.target.getAttribute("href");
lastClick.time = time;
lastClick.x = x;
lastClick.y = y;
/**
* Unfortunately Android sometimes fires click events without touch events (seen on Kindle Fire),
* so we have to add more logic to determine the time of the last click. Not perfect...
*
* Older, simpler check: if((!e.simulated) || standAlone)
*/
if((!e.simulated && (timeDiff < 500 || (timeDiff < 1500 && xyDiff[0] < 50 && xyDiff[1] < 50))) || standAlone) {
e.preventDefault();
e.stopPropagation();
if(!standAlone) return false;
}
/**
* Special logic for standalone web apps
* See http://stackoverflow.com/questions/2898740/iphone-safari-web-app-opens-links-in-new-window
*/
if(standAlone) {
window.location = target.getAttribute("href");
}
/**
* Add an energize-focus class to the targeted link (mimics :focus behavior)
* TODO: test and/or remove? Does this work?
*/
if(!target || !target.classList) return;
target.classList.add("energize-focus");
window.setTimeout(function(){
target.classList.remove("energize-focus");
}, 150);
};
/**
* closest
* @param {HTMLElement} node current node to start searching from.
* @param {string} tagName the (uppercase) name of the tag you're looking for.
*
* Find the closest ancestor tag of a given node.
*
* Starts at node and goes up the DOM tree looking for a
* matching nodeName, continuing until hitting document.body
*/
closest = function(node, tagName){
var curNode = node;
while(curNode !== document.body) { // go up the dom until we find the tag we're after
if(!curNode || curNode.nodeName === tagName) { return curNode; } // found
curNode = curNode.parentNode; // not found, so keep going up
}
return null; // not found
};
/**
* Add all delegated event listeners
*
* All the events we care about bubble up to document,
* so we can take advantage of event delegation.
*
* Note: no need to wait for DOMContentLoaded here
*/
document.addEventListener('touchstart', touchstart, false);
document.addEventListener('touchmove', touchmove, false);
document.addEventListener('touchend', touchend, false);
document.addEventListener('click', click, true); // TODO: why does this use capture?
})();

File diff suppressed because one or more lines are too long

View File

@ -1,108 +0,0 @@
/*
* jQuery Highlight plugin
*
* Based on highlight v3 by Johann Burkard
* http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
*
* Code a little bit refactored and cleaned (in my humble opinion).
* Most important changes:
* - has an option to highlight only entire words (wordsOnly - false by default),
* - has an option to be case sensitive (caseSensitive - false by default)
* - highlight element tag and class names can be specified in options
*
* Usage:
* // wrap every occurrance of text 'lorem' in content
* // with <span class='highlight'> (default options)
* $('#content').highlight('lorem');
*
* // search for and highlight more terms at once
* // so you can save some time on traversing DOM
* $('#content').highlight(['lorem', 'ipsum']);
* $('#content').highlight('lorem ipsum');
*
* // search only for entire word 'lorem'
* $('#content').highlight('lorem', { wordsOnly: true });
*
* // don't ignore case during search of term 'lorem'
* $('#content').highlight('lorem', { caseSensitive: true });
*
* // wrap every occurrance of term 'ipsum' in content
* // with <em class='important'>
* $('#content').highlight('ipsum', { element: 'em', className: 'important' });
*
* // remove default highlight
* $('#content').unhighlight();
*
* // remove custom highlight
* $('#content').unhighlight({ element: 'em', className: 'important' });
*
*
* Copyright (c) 2009 Bartek Szopka
*
* Licensed under MIT license.
*
*/
jQuery.extend({
highlight: function (node, re, nodeName, className) {
if (node.nodeType === 3) {
var match = node.data.match(re);
if (match) {
var highlight = document.createElement(nodeName || 'span');
highlight.className = className || 'highlight';
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
return 1; //skip added node in parent
}
} else if ((node.nodeType === 1 && node.childNodes) && // only element nodes that have children
!/(script|style)/i.test(node.tagName) && // ignore script and style nodes
!(node.tagName === nodeName.toUpperCase() && node.className === className)) { // skip if already highlighted
for (var i = 0; i < node.childNodes.length; i++) {
i += jQuery.highlight(node.childNodes[i], re, nodeName, className);
}
}
return 0;
}
});
jQuery.fn.unhighlight = function (options) {
var settings = { className: 'highlight', element: 'span' };
jQuery.extend(settings, options);
return this.find(settings.element + "." + settings.className).each(function () {
var parent = this.parentNode;
parent.replaceChild(this.firstChild, this);
parent.normalize();
}).end();
};
jQuery.fn.highlight = function (words, options) {
var settings = { className: 'highlight', element: 'span', caseSensitive: false, wordsOnly: false };
jQuery.extend(settings, options);
if (words.constructor === String) {
words = [words];
}
words = jQuery.grep(words, function(word, i){
return word != '';
});
words = jQuery.map(words, function(word, i) {
return word.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
});
if (words.length == 0) { return this; };
var flag = settings.caseSensitive ? "" : "i";
var pattern = "(" + words.join("|") + ")";
if (settings.wordsOnly) {
pattern = "\\b" + pattern + "\\b";
}
var re = new RegExp(pattern, flag);
return this.each(function () {
jQuery.highlight(this, re, settings.element, settings.className);
});
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -63,7 +63,7 @@ under the License.
</span>
</a>
<div class="toc-wrapper">
<%= image_tag "logo.png", class: 'logo' %>
<%= image_tag "logo.png", class: 'logo ' %>
<% if language_tabs.any? %>
<div class="lang-selector">
<% language_tabs.each do |lang| %>

View File

@ -1,38 +0,0 @@
@font-face {
font-family: 'slate';
src:font-url('slate.eot?-syv14m');
src:font-url('slate.eot?#iefix-syv14m') format('embedded-opentype'),
font-url('slate.woff2?-syv14m') format('woff2'),
font-url('slate.woff?-syv14m') format('woff'),
font-url('slate.ttf?-syv14m') format('truetype'),
font-url('slate.svg?-syv14m#slate') format('svg');
font-weight: normal;
font-style: normal;
}
%icon {
font-family: 'slate';
speak: none;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
}
%icon-exclamation-sign {
@extend %icon;
content: "\e600";
}
%icon-info-sign {
@extend %icon;
content: "\e602";
}
%icon-ok-sign {
@extend %icon;
content: "\e606";
}
%icon-search {
@extend %icon;
content: "\e607";
}

View File

@ -1,427 +0,0 @@
/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
/**
* 1. Set default font family to sans-serif.
* 2. Prevent iOS text size adjust after orientation change, without disabling
* user zoom.
*/
html {
font-family: sans-serif; /* 1 */
-ms-text-size-adjust: 100%; /* 2 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/**
* Remove default margin.
*/
body {
margin: 0;
}
/* HTML5 display definitions
========================================================================== */
/**
* Correct `block` display not defined for any HTML5 element in IE 8/9.
* Correct `block` display not defined for `details` or `summary` in IE 10/11
* and Firefox.
* Correct `block` display not defined for `main` in IE 11.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
/**
* 1. Correct `inline-block` display not defined in IE 8/9.
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
*/
audio,
canvas,
progress,
video {
display: inline-block; /* 1 */
vertical-align: baseline; /* 2 */
}
/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Address `[hidden]` styling not present in IE 8/9/10.
* Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
*/
[hidden],
template {
display: none;
}
/* Links
========================================================================== */
/**
* Remove the gray background color from active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* Improve readability when focused and also mouse hovered in all browsers.
*/
a:active,
a:hover {
outline: 0;
}
/* Text-level semantics
========================================================================== */
/**
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/**
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/**
* Address styling not present in Safari and Chrome.
*/
dfn {
font-style: italic;
}
/**
* Address variable `h1` font-size and margin within `section` and `article`
* contexts in Firefox 4+, Safari, and Chrome.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Address styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/**
* Address inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* Embedded content
========================================================================== */
/**
* Remove border when inside `a` element in IE 8/9/10.
*/
img {
border: 0;
}
/**
* Correct overflow not hidden in IE 9/10/11.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* Address margin not present in IE 8/9 and Safari.
*/
figure {
margin: 1em 40px;
}
/**
* Address differences between Firefox and other browsers.
*/
hr {
-moz-box-sizing: content-box;
box-sizing: content-box;
height: 0;
}
/**
* Contain overflow in all browsers.
*/
pre {
overflow: auto;
}
/**
* Address odd `em`-unit font size rendering in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
/* Forms
========================================================================== */
/**
* Known limitation: by default, Chrome and Safari on OS X allow very limited
* styling of `select`, unless a `border` property is set.
*/
/**
* 1. Correct color not being inherited.
* Known issue: affects color of disabled elements.
* 2. Correct font properties not being inherited.
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
*/
button,
input,
optgroup,
select,
textarea {
color: inherit; /* 1 */
font: inherit; /* 2 */
margin: 0; /* 3 */
}
/**
* Address `overflow` set to `hidden` in IE 8/9/10/11.
*/
button {
overflow: visible;
}
/**
* Address inconsistent `text-transform` inheritance for `button` and `select`.
* All other form control elements do not inherit `text-transform` values.
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
* Correct `select` style inheritance in Firefox.
*/
button,
select {
text-transform: none;
}
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"], /* 1 */
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button; /* 2 */
cursor: pointer; /* 3 */
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
html input[disabled] {
cursor: default;
}
/**
* Remove inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/**
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
input {
line-height: normal;
}
/**
* It's recommended that you don't attempt to style these elements.
* Firefox's implementation doesn't respect box-sizing, padding, or width.
*
* 1. Address box sizing set to `content-box` in IE 8/9/10.
* 2. Remove excess padding in IE 8/9/10.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
* `font-size` values of the `input`, it causes the cursor style of the
* decrement button to change from `default` to `text`.
*/
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome
* (include `-moz` to future-proof).
*/
input[type="search"] {
-webkit-appearance: textfield; /* 1 */
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /* 2 */
box-sizing: content-box;
}
/**
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
* Safari (but not Chrome) clips the cancel button when the search input has
* padding (and `textfield` appearance).
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct `color` not being inherited in IE 8/9/10/11.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0; /* 1 */
padding: 0; /* 2 */
}
/**
* Remove default vertical scrollbar in IE 8/9/10/11.
*/
textarea {
overflow: auto;
}
/**
* Don't inherit the `font-weight` (applied by a rule above).
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
*/
optgroup {
font-weight: bold;
}
/* Tables
========================================================================== */
/**
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}

View File

@ -1,140 +0,0 @@
////////////////////////////////////////////////////////////////////////////////
// RTL Styles Variables
////////////////////////////////////////////////////////////////////////////////
$default: auto;
////////////////////////////////////////////////////////////////////////////////
// TABLE OF CONTENTS
////////////////////////////////////////////////////////////////////////////////
#toc>ul>li>a>span {
float: left;
}
.toc-wrapper {
transition: right 0.3s ease-in-out !important;
left: $default !important;
#{right}: 0;
}
.toc-h2 {
padding-#{right}: $nav-padding + $nav-indent;
}
#nav-button {
#{right}: 0;
transition: right 0.3s ease-in-out;
&.open {
right: $nav-width
}
}
////////////////////////////////////////////////////////////////////////////////
// PAGE LAYOUT AND CODE SAMPLE BACKGROUND
////////////////////////////////////////////////////////////////////////////////
.page-wrapper {
margin-#{left}: $default !important;
margin-#{right}: $nav-width;
.dark-box {
#{right}: $default;
#{left}: 0;
}
}
.lang-selector {
width: $default !important;
a {
float: right;
}
}
////////////////////////////////////////////////////////////////////////////////
// CODE SAMPLE STYLES
////////////////////////////////////////////////////////////////////////////////
.content {
&>h1,
&>h2,
&>h3,
&>h4,
&>h5,
&>h6,
&>p,
&>table,
&>ul,
&>ol,
&>aside,
&>dl {
margin-#{left}: $examples-width;
margin-#{right}: $default !important;
}
&>ul,
&>ol {
padding-#{right}: $main-padding + 15px;
}
table {
th,
td {
text-align: right;
}
}
dd {
margin-#{right}: 15px;
}
aside {
aside:before {
padding-#{left}: 0.5em;
}
.search-highlight {
background: linear-gradient(to top right, #F7E633 0%, #F1D32F 100%);
}
}
pre,
blockquote {
float: left !important;
clear: left !important;
}
}
////////////////////////////////////////////////////////////////////////////////
// TYPOGRAPHY
////////////////////////////////////////////////////////////////////////////////
h1,
h2,
h3,
h4,
h5,
h6,
p,
aside {
text-align: right;
direction: rtl;
}
.toc-wrapper {
text-align: right;
direction: rtl;
font-weight: 100 !important;
}
////////////////////////////////////////////////////////////////////////////////
// RESPONSIVE DESIGN
////////////////////////////////////////////////////////////////////////////////
@media (max-width: $tablet-width) {
.toc-wrapper {
#{right}: -$nav-width;
&.open {
#{right}: 0;
}
}
.page-wrapper {
margin-#{right}: 0;
}
}
@media (max-width: $phone-width) {
%left-col {
margin-#{left}: 0;
}
}

View File

@ -1,103 +0,0 @@
/*
Copyright 2008-2013 Concur Technologies, Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
*/
////////////////////////////////////////////////////////////////////////////////
// CUSTOMIZE SLATE
////////////////////////////////////////////////////////////////////////////////
// Use these settings to help adjust the appearance of Slate
// BACKGROUND COLORS
////////////////////
$nav-bg: #2E3336 !default;
$examples-bg: #2E3336 !default;
$code-bg: #1E2224 !default;
$code-annotation-bg: #191D1F !default;
$nav-subitem-bg: #1E2224 !default;
$nav-active-bg: #0F75D4 !default;
$nav-active-parent-bg: #1E2224 !default; // parent links of the current section
$lang-select-border: #000 !default;
$lang-select-bg: #1E2224 !default;
$lang-select-active-bg: $examples-bg !default; // feel free to change this to blue or something
$lang-select-pressed-bg: #111 !default; // color of language tab bg when mouse is pressed
$main-bg: #F3F7F9 !default;
$aside-notice-bg: #8fbcd4 !default;
$aside-warning-bg: #c97a7e !default;
$aside-success-bg: #6ac174 !default;
$search-notice-bg: #c97a7e !default;
// TEXT COLORS
////////////////////
$main-text: #333 !default; // main content text color
$nav-text: #fff !default;
$nav-active-text: #fff !default;
$nav-active-parent-text: #fff !default; // parent links of the current section
$lang-select-text: #fff !default; // color of unselected language tab text
$lang-select-active-text: #fff !default; // color of selected language tab text
$lang-select-pressed-text: #fff !default; // color of language tab text when mouse is pressed
// SIZES
////////////////////
$nav-width: 230px !default; // width of the navbar
$examples-width: 50% !default; // portion of the screen taken up by code examples
$logo-margin: 0px !default; // margin below logo
$main-padding: 28px !default; // padding to left and right of content & examples
$nav-padding: 15px !default; // padding to left and right of navbar
$nav-v-padding: 10px !default; // padding used vertically around search boxes and results
$nav-indent: 10px !default; // extra padding for ToC subitems
$code-annotation-padding: 13px !default; // padding inside code annotations
$h1-margin-bottom: 21px !default; // padding under the largest header tags
$tablet-width: 930px !default; // min width before reverting to tablet size
$phone-width: $tablet-width - $nav-width !default; // min width before reverting to mobile size
// FONTS
////////////////////
%default-font {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
font-size: 14px;
}
%header-font {
@extend %default-font;
font-weight: bold;
}
%code-font {
font-family: Consolas, Menlo, Monaco, "Lucida Console", "Liberation Mono", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", "Courier New", monospace, serif;
font-size: 12px;
line-height: 1.5;
}
// OTHER
////////////////////
$nav-footer-border-color: #666 !default;
$search-box-border-color: #666 !default;
////////////////////////////////////////////////////////////////////////////////
// INTERNAL
////////////////////////////////////////////////////////////////////////////////
// These settings are probably best left alone.
%break-words {
word-break: break-all;
hyphens: auto;
}

View File

@ -1,153 +0,0 @@
@charset "utf-8";
@import 'normalize';
@import 'variables';
@import 'icon-font';
/*
Copyright 2008-2013 Concur Technologies, Inc.
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
*/
$print-color: #999;
$print-color-light: #ccc;
$print-font-size: 12px;
body {
@extend %default-font;
}
.tocify, .toc-footer, .lang-selector, .search, #nav-button {
display: none;
}
.tocify-wrapper>img {
margin: 0 auto;
display: block;
}
.content {
font-size: 12px;
pre, code {
@extend %code-font;
@extend %break-words;
border: 1px solid $print-color;
border-radius: 5px;
font-size: 0.8em;
}
pre {
code {
border: 0;
}
}
pre {
padding: 1.3em;
}
code {
padding: 0.2em;
}
table {
border: 1px solid $print-color;
tr {
border-bottom: 1px solid $print-color;
}
td,th {
padding: 0.7em;
}
}
p {
line-height: 1.5;
}
a {
text-decoration: none;
color: #000;
}
h1 {
@extend %header-font;
font-size: 2.5em;
padding-top: 0.5em;
padding-bottom: 0.5em;
margin-top: 1em;
margin-bottom: $h1-margin-bottom;
border: 2px solid $print-color-light;
border-width: 2px 0;
text-align: center;
}
h2 {
@extend %header-font;
font-size: 1.8em;
margin-top: 2em;
border-top: 2px solid $print-color-light;
padding-top: 0.8em;
}
h1+h2, h1+div+h2 {
border-top: none;
padding-top: 0;
margin-top: 0;
}
h3, h4 {
@extend %header-font;
font-size: 0.8em;
margin-top: 1.5em;
margin-bottom: 0.8em;
text-transform: uppercase;
}
h5, h6 {
text-transform: uppercase;
}
aside {
padding: 1em;
border: 1px solid $print-color-light;
border-radius: 5px;
margin-top: 1.5em;
margin-bottom: 1.5em;
line-height: 1.6;
}
aside:before {
vertical-align: middle;
padding-right: 0.5em;
font-size: 14px;
}
aside.notice:before {
@extend %icon-info-sign;
}
aside.warning:before {
@extend %icon-exclamation-sign;
}
aside.success:before {
@extend %icon-ok-sign;
}
}
.copy-clipboard {
@media print {
display: none
}
}

View File

@ -77,6 +77,7 @@ html, body {
margin: 15px auto;
max-width: 100%;
margin-bottom: $logo-margin;
max-width: 80%;
}
&>.search {

View File

@ -0,0 +1,41 @@
module Accounts
class ResetPasswordForm < ::BaseForm
# login 邮箱、手机号
# code 验证码
# type: 1手机号注册2邮箱注册
attr_accessor :login, :password, :password_confirmation, :code
validates :login, :code, :password, :password_confirmation, presence: true, allow_blank: false
validate :check!
def check!
Rails.logger.info "ResetPasswordForm params: code: #{code} login: #{login}
password: #{password} password_confirmation: #{password_confirmation}"
type = phone_mail_type(login)
db_verifi_code =
if type == 1
check_phone_format(login)
VerificationCode.where(phone: login, code: code, code_type: 2).last
elsif type == 0
check_email_format(login)
VerificationCode.where(email: login, code: code, code_type: 3).last
end
check_password(password)
check_password_confirmation(password, password_confirmation)
check_verifi_code(db_verifi_code, code)
end
def check_phone_format(phone)
phone = strip(phone)
raise LoginError, "登录名格式有误" unless phone =~ CustomRegexp::LOGIN
end
def check_email_format(mail)
mail = strip(mail)
raise EmailError, "邮件格式有误" unless mail =~ CustomRegexp::EMAIL
end
end
end

View File

@ -1,6 +1,14 @@
class BaseForm
include ActiveModel::Model
Error = Class.new(StandardError)
EmailError = Class.new(Error)
LoginError = Class.new(Error)
PhoneError = Class.new(Error)
PasswordFormatError = Class.new(Error)
VerifiCodeError = Class.new(Error)
PasswordConfirmationError = Class.new(Error)
def check_project_category(project_category_id)
unless project_category_id == ''
raise "project_category_id参数值无效." if project_category_id && !ProjectCategory.exists?(project_category_id)
@ -26,8 +34,34 @@ class BaseForm
raise "项目标识已被占用." if ReversedKeyword.check_exists?(repository_name)
end
def check_password(password)
password = strip(password)
raise PasswordFormatError, "密码8~16位密码支持字母数字和符号" unless password =~ CustomRegexp::PASSWORD
end
def check_password_confirmation(password, password_confirmation)
password = strip(password)
password_confirmation = strip(password_confirmation)
raise PasswordFormatError, "确认密码为8~16位密码支持字母数字和符号" unless password_confirmation =~ CustomRegexp::PASSWORD
raise PasswordConfirmationError, "两次输入的密码不一致" unless password == password_confirmation
end
def check_verifi_code(verifi_code, code)
code = strip(code)
# return if code == "123123" # TODO 万能验证码,用于测试
raise VerifiCodeError, "验证码已失效" if !verifi_code&.effective?
raise VerifiCodeError, "验证码不正确" if verifi_code&.code != code
end
private
def strip(str)
str.to_s.strip.presence
end
# 1 手机类型0 邮箱类型
# 注意新版的login是自动名生成的
def phone_mail_type value
value =~ /^1\d{10}$/ ? 1 : 0
end
end

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