Skip to content

Commit

Permalink
Merge pull request #301 from boostcampwm-2022/develop
Browse files Browse the repository at this point in the history
v0.2.0 배포
  • Loading branch information
asdf99245 authored Dec 13, 2022
2 parents 5b7a01e + 669d373 commit 233f2df
Show file tree
Hide file tree
Showing 21 changed files with 227 additions and 143 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# <img src="https://user-images.githubusercontent.com/79798443/206173852-a4baafe3-5de7-4afa-b494-f630d5170d54.svg"/> Devrank <img src="https://user-images.githubusercontent.com/79798443/206173852-a4baafe3-5de7-4afa-b494-f630d5170d54.svg"/>

[![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fboostcampwm-2022%2Fweb21-devrank&count_bg=%23C455F9&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com)

![Frame 12023](https://user-images.githubusercontent.com/79798443/206137429-5cb1d269-4bec-4aaa-85ad-053ae564c625.png)

**_Devrank_** 는 게임과 유사한 등급 시스템과 랭킹을 제공하여, Github 활동시 사용자에게 성취감을 주고 오픈소스 활동을 장려하는 서비스 입니다.
Expand Down
2 changes: 1 addition & 1 deletion backend/src/batch/batch.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { UserService } from '../user/user.service';
export class BatchService {
constructor(private readonly userService: UserService, private readonly configService: ConfigService) {}

@Cron('0 0 0 * * *', { name: 'cronTask' })
@Cron('0 0 0 * * *', { name: 'cronTask', timeZone: 'Asia/Seoul' })
handleCron() {
logger.log('Task Called');
this.userService.dailyUpdateAllUsers(this.configService.get('GITHUB_PERSONAL_ACCESS_TOKEN'));
Expand Down
10 changes: 4 additions & 6 deletions backend/src/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Controller,
DefaultValuePipe,
Get,
NotFoundException,
Param,
ParseIntPipe,
Patch,
Expand Down Expand Up @@ -74,18 +75,15 @@ export class UserController {
@Param('username') username: string,
): Promise<UserProfileDto> {
const lowerUsername = username.toLowerCase();
if (
(await this.userService.findUpdateScoreTimeToLive(lowerUsername)) > 0 &&
(await this.userService.findOneByFilter({ lowerUsername }))?.id !== id
) {
const targetUser = await this.userService.findOneByFilter({ lowerUsername });
if ((await this.userService.findUpdateScoreTimeToLive(lowerUsername)) > 0 && targetUser?.id !== id) {
throw new BadRequestException('user score has been updated recently.');
}
await this.userService.setUpdateScoreDelayTime(lowerUsername, UPDATE_DELAY_TIME);
const user = await this.userService.updateUser(
lowerUsername,
githubToken || this.configService.get('GITHUB_PERSONAL_ACCESS_TOKEN'),
);

await this.userService.setUpdateScoreDelayTime(lowerUsername, UPDATE_DELAY_TIME);
user.updateDelayTime = UPDATE_DELAY_TIME + 3;
return user;
}
Expand Down
76 changes: 33 additions & 43 deletions backend/src/user/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,28 @@ export class UserService {
}

async findOneByUsername(githubToken: string, ip: string, lowerUsername: string): Promise<UserProfileDto> {
let user = null;
if (await this.userRepository.isDuplicatedRequestIp(ip, lowerUsername)) {
user = await this.userRepository.findOneByLowerUsername(lowerUsername);
} else {
user = await this.userRepository.findOneByLowerUsernameAndUpdateViews(lowerUsername);
}

let user = await this.userRepository.findOneByLowerUsername(lowerUsername);
if (!user) {
user = await this.updateUser(lowerUsername, githubToken);
if (!user.scoreHistory) {
user.scoreHistory = [];
try {
user = await this.updateUser(lowerUsername, githubToken);
if (!user.scoreHistory) {
user.scoreHistory = [];
}
user.scoreHistory.push({ date: new Date(), score: user.score });
user = await this.userRepository.createOrUpdate(user);
} catch {
throw new HttpException(`can't update this user.`, HttpStatus.NO_CONTENT);
}
user.scoreHistory.push({ date: new Date(), score: user.score });
user = await this.userRepository.createOrUpdate(user);
}
await this.userRepository.createOrUpdate(user);

const { totalRank, tierRank } =
(await this.getUserRelativeRanking(user)) || (await this.setUserRelativeRanking(user));
if (!(await this.userRepository.isDuplicatedRequestIp(ip, lowerUsername)) && user.history) {
user.dailyViews += 1;
await this.userRepository.createOrUpdate(user);
}
this.userRepository.setDuplicatedRequestIp(ip, lowerUsername);
user.updateDelayTime = await this.userRepository.findUpdateScoreTimeToLive(lowerUsername);
user.totalRank = totalRank;
user.tierRank = tierRank;
user.startExp = getStartExp(user.score);
user.needExp = getNeedExp(user.score);
return user;
return { ...user, totalRank, tierRank, startExp: getStartExp(user.score), needExp: getNeedExp(user.score) };
}

async findAllByPrefixUsername(limit: number, lowerUsername: string): Promise<AutoCompleteDto[]> {
Expand All @@ -83,6 +79,24 @@ export class UserService {
organizations,
pinnedRepositories,
};
if (!updatedUser.scoreHistory) {
updatedUser.scoreHistory = [];
}
const KR_TIME_DIFF = 9 * 60 * 60 * 1000;
const utc = updatedUser.scoreHistory[updatedUser.scoreHistory.length - 1].date.getTime();
if (new Date(utc + KR_TIME_DIFF).getDate() == new Date().getDate()) {
updatedUser.scoreHistory.pop();
}
updatedUser.scoreHistory.push({
date: new Date(),
score: updatedUser.score,
});
if (updatedUser.scoreHistory.length > 1) {
updatedUser.scoreDifference =
updatedUser.score - updatedUser.scoreHistory[updatedUser.scoreHistory.length - 2].score;
} else {
updatedUser.scoreDifference = 0;
}
user = await this.userRepository.createOrUpdate(updatedUser);
const { totalRank, tierRank } = await this.setUserRelativeRanking(user);
const userWithRank: UserProfileDto = {
Expand All @@ -102,15 +116,6 @@ export class UserService {
await sleep(GITHUB_API_DELAY);
try {
const updateUser = await this.updateUser(user.lowerUsername, githubToken);
if (!updateUser.scoreHistory) updateUser.scoreHistory = [];
if (updateUser.scoreHistory.length) updateUser.scoreHistory.pop();
updateUser.scoreHistory.push({ date: new Date(), score: updateUser.score });
if (updateUser.scoreHistory.length > 1) {
updateUser.scoreDifference =
updateUser.score - updateUser.scoreHistory[updateUser.scoreHistory.length - 2].score;
} else {
updateUser.scoreDifference = 0;
}
this.userRepository.createOrUpdate(updateUser);
this.userRepository.deleteCachedUserRank(updateUser.lowerUsername + '&');
} catch {
Expand All @@ -126,17 +131,6 @@ export class UserService {
await sleep(GITHUB_API_DELAY);
try {
const updatedUser = await this.updateUser(user.lowerUsername, githubToken);
if (!updatedUser.scoreHistory) updatedUser.scoreHistory = [];
updatedUser.scoreHistory.push({
date: new Date(),
score: updatedUser.score,
});
if (updatedUser.scoreHistory.length > 1) {
updatedUser.scoreDifference =
updatedUser.score - updatedUser.scoreHistory[updatedUser.scoreHistory.length - 2].score;
} else {
updatedUser.scoreDifference = 0;
}
updatedUser.dailyViews = 0;
this.userRepository.createOrUpdate(updatedUser);
} catch {
Expand Down Expand Up @@ -202,20 +196,16 @@ export class UserService {
username: lowerUsername,
id,
});

const personalResponse: any = await octokit.graphql(nonForkRepositoryQuery, {
username: lowerUsername,
id,
});

const followersResponse: any = await octokit.graphql(followersQuery, {
username: lowerUsername,
});

const issuesResponse: any = await octokit.graphql(issueQuery, {
username: lowerUsername,
});

let languagesScore = new Map();
function getCommitScore(acc: number, repository) {
if (!repository.defaultBranchRef) {
Expand Down
21 changes: 0 additions & 21 deletions frontend/public/icons/cube-large-background.svg

This file was deleted.

21 changes: 21 additions & 0 deletions frontend/public/icons/cube/cube-small-invalid.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion frontend/public/locales/en/profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
"user-update-delay": "You can update it in",
"day": "day",
"total": "Total",
"rank": "Rank"
"rank": "Rank",
"invalid-user": "This user cannot get information",
"invalid-rank": "Unable to get the rank"
}
4 changes: 3 additions & 1 deletion frontend/public/locales/ko/profile.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@
"user-update-delay": "초 후 업데이트 가능합니다.",
"day": "",
"total": "전체",
"rank": "등급"
"rank": "등급",
"invalid-user": "정보를 가져올 수 없는 유저입니다",
"invalid-rank": "등수를 표시할 수 없습니다"
}
1 change: 1 addition & 0 deletions frontend/src/components/Chart/LineChart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function LineChart({ data, min, max, markers, tooltip }: LineChartProps) {
margin={{ top: 60, right: 60, bottom: 60, left: 60 }}
curve='monotoneX'
enableArea={true}
areaBaselineValue={min || 0}
xScale={{
type: 'time',
format: '%Y-%m-%d',
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/Chart/theme.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"legend": {
"text": {
"fontSize": 14,
"fontWeight": 700,
"fontWeight": 400,
"fill": "#FBFBFB"
}
},
Expand All @@ -39,7 +39,8 @@
"strokeWidth": 1
},
"text": {
"fontSize": 14,
"fontSize": 12,
"fontWeight": 100,
"fill": "#FBFBFB"
}
}
Expand Down
13 changes: 6 additions & 7 deletions frontend/src/components/Header/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import styled from 'styled-components';
import { useMutation, useQuery } from '@tanstack/react-query';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { Avatar, Button } from '@components/common';
import Dropdown from '@components/common/Dropdown';
import { requestTokenRefresh, requestUserLogout } from '@apis/auth';
import { GITHUB_AUTH_REQUEST_URL } from '@utils/constants';

function Header() {
const queryClient = useQueryClient();

const { mutate: logout } = useMutation({
mutationFn: requestUserLogout,
onSuccess: () => queryClient.invalidateQueries(['user']),
});

const router = useRouter();

const {
isLoading,
data: userData,
remove: removeUser,
} = useQuery(['user'], () => requestTokenRefresh(), {
const { isLoading, data: userData } = useQuery(['user'], () => requestTokenRefresh(), {
enabled: router.pathname !== '/callback',
cacheTime: Infinity,
});
Expand All @@ -33,7 +33,6 @@ function Header() {

const onClickLogoutButton = () => {
logout();
removeUser();
};

return (
Expand Down
47 changes: 27 additions & 20 deletions frontend/src/components/Profile/ProfileCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface ProfileCardProps {
updateData: () => void;
isLoading: boolean;
isMine: boolean;
isInvalid: boolean;
};
}

Expand All @@ -53,6 +54,7 @@ function ProfileCard({ profileData }: ProfileCardProps) {
updateData,
isLoading,
isMine,
isInvalid,
} = profileData;

const { t } = useTranslation(['profile', 'tier']);
Expand Down Expand Up @@ -119,18 +121,24 @@ function ProfileCard({ profileData }: ProfileCardProps) {
)}
</ProfileInfos>
<ProfileRank>
<CubeLogo tier={tier} size={'sm'} />
<div>
<p>
{t('profile:total')}&nbsp;{totalRank}
{getRankingUnit(locale, totalRank)}
</p>
<p>
<ColorPoint color={CUBE_COLOR_MAP[tier]}>{t(`tier:${tier}`)}</ColorPoint>
&nbsp;{tierRank}
{getRankingUnit(locale, tierRank)}
</p>
</div>
<CubeLogo tier={tier} size={'sm'} isInvalid={isInvalid} />
{isInvalid ? (
<RankText>
<p>{t('profile:invalid-rank')}</p>
</RankText>
) : (
<RankText>
<p>
{t('profile:total')}&nbsp;{totalRank}
{getRankingUnit(locale, totalRank)}
</p>
<p>
<ColorPoint color={CUBE_COLOR_MAP[tier]}>{t(`tier:${tier}`)}</ColorPoint>
&nbsp;{tierRank}
{getRankingUnit(locale, tierRank)}
</p>
</RankText>
)}
</ProfileRank>
</Paper>
);
Expand Down Expand Up @@ -172,15 +180,14 @@ const ProfileInfos = styled.ul`
const ProfileRank = styled.div`
max-width: 300px;
width: 100%;
div {
margin-top: 20px;
${({ theme }) => theme.common.flexCenterColumn};
p {
margin-top: 8px;
}
}
${({ theme }) => theme.common.flexCenterColumn};
`;

transform: translateZ(-50);
const RankText = styled.div`
margin-top: 20px;
p {
margin-top: 8px;
}
`;

const ImageStyle = {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/Ranking/NotFound/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function NotFound() {
<Container className={aldrich.className}>
<div>
<CubeImage
src='/icons/cube-large-background.svg'
src='/icons/cube/cube-small-invalid.svg'
alt='큐브 이미지'
width={220}
height={250}
Expand Down Expand Up @@ -44,6 +44,7 @@ const Container = styled.div`
}
`;
const CubeImage = styled(Image)`
z-index: -1;
position: absolute;
top: 40%;
left: 50%;
Expand Down
Loading

0 comments on commit 233f2df

Please sign in to comment.