Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ pom.xml.releaseBackup
# Spring Boot
*.log
.env
credentials.json
tokens/

# H2 local DB
data/
Expand Down
18 changes: 18 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Google API Client (1.x系に固定) -->
<dependency>
<groupId>com.google.api-client</groupId>
<artifactId>google-api-client</artifactId>
<version>1.34.1</version>
</dependency>
<!-- OAuth -->
<dependency>
<groupId>com.google.oauth-client</groupId>
<artifactId>google-oauth-client-jetty</artifactId>
<version>1.34.1</version>
</dependency>
<!-- Calendar API -->
<dependency>
<groupId>com.google.apis</groupId>
<artifactId>google-api-services-calendar</artifactId>
<version>v3-rev20220715-2.0.0</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.example.routineapp.config;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.CalendarScopes;

@Configuration
public class GoogleCalendarConfig {

private static final String APPLICATION_NAME = "Google Calendar API";
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
private static final String TOKENS_DIRECTORY_PATH = "tokens";
private static final List<String> SCOPES =
Collections.singletonList(CalendarScopes.CALENDAR_READONLY);
private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

@Bean
public Calendar googleCalendar() throws IOException, GeneralSecurityException {
NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
Credential credential = getCredentials(httpTransport);

return new Calendar.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME)
.build();
}

private Credential getCredentials(NetHttpTransport httpTransport) throws IOException {
InputStream in = getClass().getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}

GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets, SCOPES)
.setDataStoreFactory(
new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();

LocalServerReceiver receiver =
new LocalServerReceiver.Builder().setPort(8888).build();

return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.example.routineapp.controller;

import java.io.IOException;
import java.util.List;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.routineapp.service.GoogleCalendarService;
import com.google.api.services.calendar.model.Event;

@RestController
public class CalendarController {

private final GoogleCalendarService calendarService;

public CalendarController(GoogleCalendarService calendarService) {
this.calendarService = calendarService;
}

@GetMapping("/calendar/events")
public List<Event> getEvents() throws IOException {
return calendarService.getUpcomingEvents(10);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.example.routineapp.service;

import java.io.IOException;
import java.util.List;

import org.springframework.stereotype.Service;

import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.Calendar;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.Events;

@Service
public class GoogleCalendarService {

private final Calendar calendar;

public GoogleCalendarService(Calendar calendar) {
this.calendar = calendar;
}

public List<Event> getUpcomingEvents(int maxResults) throws IOException {
DateTime now = new DateTime(System.currentTimeMillis());

Events events = calendar.events()
.list("primary")
.setTimeMin(now)
.setMaxResults(maxResults)
.setOrderBy("startTime")
.setSingleEvents(true)
.execute();

return events.getItems();
}
}
8 changes: 4 additions & 4 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ spring:
chain:
cache: false
datasource:
url: jdbc:postgresql://${DATABASE_HOST}:${DATABASE_PORT}/${DATABASE_NAME}
username: ${DATABASE_USERNAME}
password: ${DATABASE_PASSWORD}
url: jdbc:postgresql://${DATABASE_HOST:localhost}:${DATABASE_PORT:5433}/${DATABASE_NAME:routine_db}
username: ${DATABASE_USERNAME:postgres}
password: ${DATABASE_PASSWORD:postgres}
driver-class-name: org.postgresql.Driver
hikari:
maximum-pool-size: 5
Expand All @@ -33,7 +33,7 @@ spring:
open-in-view: false

server:
port: ${PORT:8080} # Render が割り当てるポート
port: ${PORT:8080} # Render が割り当てるポート、ローカルは8080

logging:
level:
Expand Down
23 changes: 1 addition & 22 deletions src/main/resources/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -369,25 +369,4 @@ body {

.day-name-ja {
font-weight: 600;
}

.week-grid {
display: grid;
grid-template-columns: repeat(7, 1fr); /* 7日分 */
gap: 1rem;
}

.day-card {
background: #fff;
border-radius: 8px;
padding: 1rem;
min-height: 180px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
}

.day-name-ja {
font-size: 1.1rem;
font-weight: bold;
margin-bottom: 0.5rem;
text-align: center;
}
}
Loading