Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
2
2021-155
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
2021-155
2021-155
Commits
b5d62d07
Commit
b5d62d07
authored
Jul 01, 2021
by
Kamal Thennakoon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
calculate score based on git stats
parent
9ca7180d
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
390 additions
and
0 deletions
+390
-0
github-scorer-cloud/services/common/blacklist.js
github-scorer-cloud/services/common/blacklist.js
+3
-0
github-scorer-cloud/services/common/calculateRank.js
github-scorer-cloud/services/common/calculateRank.js
+93
-0
github-scorer-cloud/services/common/retryer.js
github-scorer-cloud/services/common/retryer.js
+43
-0
github-scorer-cloud/services/common/utils.js
github-scorer-cloud/services/common/utils.js
+251
-0
No files found.
github-scorer-cloud/services/common/blacklist.js
0 → 100644
View file @
b5d62d07
const
blacklist
=
[
"
renovate-bot
"
,
"
technote-space
"
,
"
sw-yx
"
];
module
.
exports
=
blacklist
;
\ No newline at end of file
github-scorer-cloud/services/common/calculateRank.js
0 → 100644
View file @
b5d62d07
// https://stackoverflow.com/a/5263759/10629172
function
normalcdf
(
mean
,
sigma
,
to
)
{
var
z
=
(
to
-
mean
)
/
Math
.
sqrt
(
2
*
sigma
*
sigma
);
var
t
=
1
/
(
1
+
0.3275911
*
Math
.
abs
(
z
));
var
a1
=
0.254829592
;
var
a2
=
-
0.284496736
;
var
a3
=
1.421413741
;
var
a4
=
-
1.453152027
;
var
a5
=
1.061405429
;
var
erf
=
1
-
((((
a5
*
t
+
a4
)
*
t
+
a3
)
*
t
+
a2
)
*
t
+
a1
)
*
t
*
Math
.
exp
(
-
z
*
z
);
var
sign
=
1
;
if
(
z
<
0
)
{
sign
=
-
1
;
}
return
(
1
/
2
)
*
(
1
+
sign
*
erf
);
}
function
calculateRank
({
totalRepos
,
totalCommits
,
contributions
,
followers
,
prs
,
issues
,
stargazers
,
})
{
const
COMMITS_OFFSET
=
1.65
;
const
CONTRIBS_OFFSET
=
1.65
;
const
ISSUES_OFFSET
=
1
;
const
STARS_OFFSET
=
0.75
;
const
PRS_OFFSET
=
0.5
;
const
FOLLOWERS_OFFSET
=
0.45
;
const
REPO_OFFSET
=
1
;
const
ALL_OFFSETS
=
CONTRIBS_OFFSET
+
ISSUES_OFFSET
+
STARS_OFFSET
+
PRS_OFFSET
+
FOLLOWERS_OFFSET
+
REPO_OFFSET
;
const
RANK_S_VALUE
=
1
;
const
RANK_DOUBLE_A_VALUE
=
25
;
const
RANK_A2_VALUE
=
45
;
const
RANK_A3_VALUE
=
60
;
const
RANK_B_VALUE
=
100
;
const
TOTAL_VALUES
=
RANK_S_VALUE
+
RANK_A2_VALUE
+
RANK_A3_VALUE
+
RANK_B_VALUE
;
// prettier-ignore
const
score
=
(
totalCommits
*
COMMITS_OFFSET
+
contributions
*
CONTRIBS_OFFSET
+
issues
*
ISSUES_OFFSET
+
stargazers
*
STARS_OFFSET
+
prs
*
PRS_OFFSET
+
followers
*
FOLLOWERS_OFFSET
+
totalRepos
*
REPO_OFFSET
)
/
100
;
const
normalizedScore
=
normalcdf
(
score
,
TOTAL_VALUES
,
ALL_OFFSETS
)
*
100
;
let
level
=
""
;
if
(
normalizedScore
<
RANK_S_VALUE
)
{
level
=
"
95%+
"
;
}
if
(
normalizedScore
>=
RANK_S_VALUE
&&
normalizedScore
<
RANK_DOUBLE_A_VALUE
)
{
level
=
"
80%+
"
;
}
if
(
normalizedScore
>=
RANK_DOUBLE_A_VALUE
&&
normalizedScore
<
RANK_A2_VALUE
)
{
level
=
"
70%+
"
;
}
if
(
normalizedScore
>=
RANK_A2_VALUE
&&
normalizedScore
<
RANK_A3_VALUE
)
{
level
=
"
50%+
"
;
}
if
(
normalizedScore
>=
RANK_A3_VALUE
&&
normalizedScore
<
RANK_B_VALUE
)
{
level
=
"
30%+
"
;
}
return
{
level
,
score
:
normalizedScore
};
}
module
.
exports
=
calculateRank
;
github-scorer-cloud/services/common/retryer.js
0 → 100644
View file @
b5d62d07
const
{
logger
,
CustomError
}
=
require
(
"
../common/utils
"
);
const
retryer
=
async
(
fetcher
,
variables
,
retries
=
0
)
=>
{
if
(
retries
>
7
)
{
throw
new
CustomError
(
"
Maximum retries exceeded
"
,
CustomError
.
MAX_RETRY
);
}
try
{
// try to fetch with the first token since RETRIES is 0 index i'm adding +1
let
response
=
await
fetcher
(
variables
,
process
.
env
[
`PAT_
${
retries
+
1
}
`
],
retries
,
);
// prettier-ignore
const
isRateExceeded
=
response
.
data
.
errors
&&
response
.
data
.
errors
[
0
].
type
===
"
RATE_LIMITED
"
;
// if rate limit is hit increase the RETRIES and recursively call the retryer
// with username, and current RETRIES
if
(
isRateExceeded
)
{
logger
.
log
(
`PAT_
${
retries
+
1
}
Failed`
);
retries
++
;
// directly return from the function
return
retryer
(
fetcher
,
variables
,
retries
);
}
// finally return the response
return
response
;
}
catch
(
err
)
{
// prettier-ignore
// also checking for bad credentials if any tokens gets invalidated
const
isBadCredential
=
err
.
response
.
data
&&
err
.
response
.
data
.
message
===
"
Bad credentials
"
;
if
(
isBadCredential
)
{
logger
.
log
(
`PAT_
${
retries
+
1
}
Failed`
);
retries
++
;
// directly return from the function
return
retryer
(
fetcher
,
variables
,
retries
);
}
}
};
module
.
exports
=
retryer
;
github-scorer-cloud/services/common/utils.js
0 → 100644
View file @
b5d62d07
const
axios
=
require
(
"
axios
"
);
const
wrap
=
require
(
"
word-wrap
"
);
const
themes
=
require
(
"
../../themes
"
);
const
renderError
=
(
message
,
secondaryMessage
=
""
)
=>
{
return
`
<svg width="495" height="120" viewBox="0 0 495 120" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
.text { font: 600 16px 'Segoe UI', Ubuntu, Sans-Serif; fill: #2F80ED }
.small { font: 600 12px 'Segoe UI', Ubuntu, Sans-Serif; fill: #252525 }
.gray { fill: #858585 }
</style>
<rect x="0.5" y="0.5" width="494" height="99%" rx="4.5" fill="#FFFEFE" stroke="#E4E2E2"/>
<text x="25" y="45" class="text">Something went wrong! file an issue at https://git.io/JJmN9</text>
<text data-testid="message" x="25" y="55" class="text small">
<tspan x="25" dy="18">
${
encodeHTML
(
message
)}
</tspan>
<tspan x="25" dy="18" class="gray">
${
secondaryMessage
}
</tspan>
</text>
</svg>
`
;
};
// https://stackoverflow.com/a/48073476/10629172
function
encodeHTML
(
str
)
{
return
str
.
replace
(
/
[\u
00A0-
\u
9999<>&
](?!
#
)
/gim
,
(
i
)
=>
{
return
"
&#
"
+
i
.
charCodeAt
(
0
)
+
"
;
"
;
})
.
replace
(
/
\u
0008/gim
,
""
);
}
function
kFormatter
(
num
)
{
return
Math
.
abs
(
num
)
>
999
?
Math
.
sign
(
num
)
*
(
Math
.
abs
(
num
)
/
1000
).
toFixed
(
1
)
+
"
k
"
:
Math
.
sign
(
num
)
*
Math
.
abs
(
num
);
}
function
isValidHexColor
(
hexColor
)
{
return
new
RegExp
(
/^
([
A-Fa-f0-9
]{8}
|
[
A-Fa-f0-9
]{6}
|
[
A-Fa-f0-9
]{3}
|
[
A-Fa-f0-9
]{4})
$/
,
).
test
(
hexColor
);
}
function
parseBoolean
(
value
)
{
if
(
value
===
"
true
"
)
{
return
true
;
}
else
if
(
value
===
"
false
"
)
{
return
false
;
}
else
{
return
value
;
}
}
function
parseArray
(
str
)
{
if
(
!
str
)
return
[];
return
str
.
split
(
"
,
"
);
}
function
clampValue
(
number
,
min
,
max
)
{
return
Math
.
max
(
min
,
Math
.
min
(
number
,
max
));
}
function
isValidGradient
(
colors
)
{
return
isValidHexColor
(
colors
[
1
])
&&
isValidHexColor
(
colors
[
2
]);
}
function
fallbackColor
(
color
,
fallbackColor
)
{
let
colors
=
color
.
split
(
"
,
"
);
let
gradient
=
null
;
if
(
colors
.
length
>
1
&&
isValidGradient
(
colors
))
{
gradient
=
colors
;
}
return
(
(
gradient
?
gradient
:
isValidHexColor
(
color
)
&&
`#
${
color
}
`
)
||
fallbackColor
);
}
function
request
(
data
,
headers
)
{
return
axios
({
url
:
"
https://api.github.com/graphql
"
,
method
:
"
post
"
,
headers
,
data
,
});
}
/**
*
* @param {String[]} items
* @param {Number} gap
* @param {string} direction
*
* @description
* Auto layout utility, allows us to layout things
* vertically or horizontally with proper gaping
*/
function
flexLayout
({
items
,
gap
,
direction
})
{
// filter() for filtering out empty strings
return
items
.
filter
(
Boolean
).
map
((
item
,
i
)
=>
{
let
transform
=
`translate(
${
gap
*
i
}
, 0)`
;
if
(
direction
===
"
column
"
)
{
transform
=
`translate(0,
${
gap
*
i
}
)`
;
}
return
`<g transform="
${
transform
}
">
${
item
}
</g>`
;
});
}
// returns theme based colors with proper overrides and defaults
function
getCardColors
({
title_color
,
text_color
,
icon_color
,
bg_color
,
theme
,
border_color
,
fallbackTheme
=
"
default
"
,
})
{
const
defaultTheme
=
themes
[
fallbackTheme
];
const
selectedTheme
=
themes
[
theme
]
||
defaultTheme
;
const
defaultBorderColor
=
selectedTheme
.
border_color
||
defaultTheme
.
border_color
;
// get the color provided by the user else the theme color
// finally if both colors are invalid fallback to default theme
const
titleColor
=
fallbackColor
(
title_color
||
selectedTheme
.
title_color
,
"
#
"
+
defaultTheme
.
title_color
,
);
const
iconColor
=
fallbackColor
(
icon_color
||
selectedTheme
.
icon_color
,
"
#
"
+
defaultTheme
.
icon_color
,
);
const
textColor
=
fallbackColor
(
text_color
||
selectedTheme
.
text_color
,
"
#
"
+
defaultTheme
.
text_color
,
);
const
bgColor
=
fallbackColor
(
bg_color
||
selectedTheme
.
bg_color
,
"
#
"
+
defaultTheme
.
bg_color
,
);
const
borderColor
=
fallbackColor
(
border_color
||
defaultBorderColor
,
"
#
"
+
defaultBorderColor
,
);
return
{
titleColor
,
iconColor
,
textColor
,
bgColor
,
borderColor
};
}
function
wrapTextMultiline
(
text
,
width
=
60
,
maxLines
=
3
)
{
const
wrapped
=
wrap
(
encodeHTML
(
text
),
{
width
})
.
split
(
"
\n
"
)
// Split wrapped lines to get an array of lines
.
map
((
line
)
=>
line
.
trim
());
// Remove leading and trailing whitespace of each line
const
lines
=
wrapped
.
slice
(
0
,
maxLines
);
// Only consider maxLines lines
// Add "..." to the last line if the text exceeds maxLines
if
(
wrapped
.
length
>
maxLines
)
{
lines
[
maxLines
-
1
]
+=
"
...
"
;
}
// Remove empty lines if text fits in less than maxLines lines
const
multiLineText
=
lines
.
filter
(
Boolean
);
return
multiLineText
;
}
const
noop
=
()
=>
{};
// return console instance based on the environment
const
logger
=
process
.
env
.
NODE_ENV
!==
"
test
"
?
console
:
{
log
:
noop
,
error
:
noop
};
const
CONSTANTS
=
{
THIRTY_MINUTES
:
1800
,
TWO_HOURS
:
7200
,
FOUR_HOURS
:
14400
,
ONE_DAY
:
86400
,
};
const
SECONDARY_ERROR_MESSAGES
=
{
MAX_RETRY
:
"
Please add an env variable called PAT_1 with your github token in vercel
"
,
USER_NOT_FOUND
:
"
Make sure the provided username is not an organization
"
,
};
class
CustomError
extends
Error
{
constructor
(
message
,
type
)
{
super
(
message
);
this
.
type
=
type
;
this
.
secondaryMessage
=
SECONDARY_ERROR_MESSAGES
[
type
]
||
"
adsad
"
;
}
static
MAX_RETRY
=
"
MAX_RETRY
"
;
static
USER_NOT_FOUND
=
"
USER_NOT_FOUND
"
;
}
// https://stackoverflow.com/a/48172630/10629172
function
measureText
(
str
,
fontSize
=
10
)
{
// prettier-ignore
const
widths
=
[
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0.2796875
,
0.2765625
,
0.3546875
,
0.5546875
,
0.5546875
,
0.8890625
,
0.665625
,
0.190625
,
0.3328125
,
0.3328125
,
0.3890625
,
0.5828125
,
0.2765625
,
0.3328125
,
0.2765625
,
0.3015625
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.2765625
,
0.2765625
,
0.584375
,
0.5828125
,
0.584375
,
0.5546875
,
1.0140625
,
0.665625
,
0.665625
,
0.721875
,
0.721875
,
0.665625
,
0.609375
,
0.7765625
,
0.721875
,
0.2765625
,
0.5
,
0.665625
,
0.5546875
,
0.8328125
,
0.721875
,
0.7765625
,
0.665625
,
0.7765625
,
0.721875
,
0.665625
,
0.609375
,
0.721875
,
0.665625
,
0.94375
,
0.665625
,
0.665625
,
0.609375
,
0.2765625
,
0.3546875
,
0.2765625
,
0.4765625
,
0.5546875
,
0.3328125
,
0.5546875
,
0.5546875
,
0.5
,
0.5546875
,
0.5546875
,
0.2765625
,
0.5546875
,
0.5546875
,
0.221875
,
0.240625
,
0.5
,
0.221875
,
0.8328125
,
0.5546875
,
0.5546875
,
0.5546875
,
0.5546875
,
0.3328125
,
0.5
,
0.2765625
,
0.5546875
,
0.5
,
0.721875
,
0.5
,
0.5
,
0.5
,
0.3546875
,
0.259375
,
0.353125
,
0.5890625
,
];
const
avg
=
0.5279276315789471
;
return
(
str
.
split
(
""
)
.
map
((
c
)
=>
c
.
charCodeAt
(
0
)
<
widths
.
length
?
widths
[
c
.
charCodeAt
(
0
)]
:
avg
,
)
.
reduce
((
cur
,
acc
)
=>
acc
+
cur
)
*
fontSize
);
}
module
.
exports
=
{
renderError
,
kFormatter
,
encodeHTML
,
isValidHexColor
,
request
,
parseArray
,
parseBoolean
,
fallbackColor
,
flexLayout
,
getCardColors
,
clampValue
,
wrapTextMultiline
,
measureText
,
logger
,
CONSTANTS
,
CustomError
,
};
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment