-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: pubg integration #631
base: main
Are you sure you want to change the base?
Conversation
WalkthroughThe integration of PUBG API support enhances the application by incorporating PUBG data alongside existing features. This update includes adding environment variables, configuring settings, and implementing new functionality across various components like the API, parser, and frontend. It introduces a new PUBG client, updates caching mechanisms for PUBG data, and extends the database schema to accommodate PUBG integrations. Changes
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (invoked as PR comments)
Additionally, you can add CodeRabbit Configration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review Status
Actionable comments generated: 7
Configuration used: CodeRabbit UI
Files ignored due to path filters (10)
apps/api/go.mod
is excluded by:!**/*.mod
apps/api/go.sum
is excluded by:!**/*.sum
apps/parser/go.mod
is excluded by:!**/*.mod
apps/parser/go.sum
is excluded by:!**/*.sum
frontend/dashboard/src/assets/integrations/pubg.svg
is excluded by:!**/*.svg
frontend/dashboard/src/locales/en.json
is excluded by:!**/*.json
go.work
is excluded by:!**/*.work
go.work.sum
is excluded by:!**/*.sum
libs/pubg/go.mod
is excluded by:!**/*.mod
libs/pubg/go.sum
is excluded by:!**/*.sum
Files selected for processing (30)
- .env.example (1 hunks)
- apps/api/app/app.go (3 hunks)
- apps/api/internal/impl_protected/impl_protected.go (3 hunks)
- apps/api/internal/impl_protected/integrations/integrations.go (1 hunks)
- apps/api/internal/impl_protected/integrations/pubg.go (1 hunks)
- apps/parser/cmd/main.go (3 hunks)
- apps/parser/internal/cacher/cacher.go (3 hunks)
- apps/parser/internal/cacher/pubg.go (1 hunks)
- apps/parser/internal/types/pubg_api.go (1 hunks)
- apps/parser/internal/types/services/services.go (2 hunks)
- apps/parser/internal/types/variables_cacher.go (2 hunks)
- apps/parser/internal/variables/pubg/lifetime/duo.go (1 hunks)
- apps/parser/internal/variables/pubg/lifetime/solo.go (1 hunks)
- apps/parser/internal/variables/pubg/lifetime/squad.go (1 hunks)
- apps/parser/internal/variables/pubg/season/duo.go (1 hunks)
- apps/parser/internal/variables/pubg/season/solo.go (1 hunks)
- apps/parser/internal/variables/pubg/season/squad.go (1 hunks)
- apps/parser/internal/variables/variables.go (2 hunks)
- frontend/dashboard/src/api/integrations/index.ts (1 hunks)
- frontend/dashboard/src/api/integrations/pubg.ts (1 hunks)
- frontend/dashboard/src/components/integrations/pubg.vue (1 hunks)
- frontend/dashboard/src/pages/Integrations.vue (2 hunks)
- libs/api/api.proto (2 hunks)
- libs/api/messages/integrations_pubg/integrations_pubg.proto (1 hunks)
- libs/config/config.go (2 hunks)
- libs/config/src/index.js (1 hunks)
- libs/gomodels/integrations.go (1 hunks)
- libs/migrations/migrations/20240315145552_pubg_integration.sql (1 hunks)
- libs/migrations/seeds/integrations.go (1 hunks)
- libs/pubg/pubg.go (1 hunks)
Files skipped from review due to trivial changes (1)
- apps/parser/internal/variables/pubg/season/duo.go
Additional comments: 35
frontend/dashboard/src/api/integrations/index.ts (1)
- 6-6: The addition of the PUBG integration export (
export * from './pubg.js';
) is correctly implemented and aligns with the PR's objectives to integrate PUBG API functionality into the application.libs/migrations/migrations/20240315145552_pubg_integration.sql (1)
- 1-10: The SQL migration for adding the
PUBG
value to theintegrations_service_enum
type is correctly implemented. However, it's worth noting that the down migration does not remove the added enum value, which is a common practice due to the complexity of altering enum types in PostgreSQL. Consider adding a comment to clarify this decision for future maintainers.libs/api/messages/integrations_pubg/integrations_pubg.proto (1)
- 1-11: The protobuf definitions for PUBG integrations are correctly implemented and align with the PR's objectives. While the current structures are sufficient for handling nicknames, consider planning for future expansions that might require more complex data structures.
apps/parser/internal/types/pubg_api.go (1)
- 1-18: The Go structures defined for handling PUBG data are well-structured and seem to align with the expected data from the PUBG API. Ensure that these structures remain aligned with the PUBG API data and consider the stability and updates of the third-party library
github.com/NovikovRoman/pubg
used here.frontend/dashboard/src/api/integrations/pubg.ts (1)
- 1-27: The Vue.js composition API hooks for PUBG integration are correctly implemented and align with the PR's objectives. Consider adding error handling for the API calls to improve the user experience in case of failures or issues with the PUBG API.
.env.example (1)
- 46-46: The addition of the
PUBG_API_KEYS
environment variable is correctly implemented and essential for the PUBG API integration, allowing the application to utilize multiple API keys. This is a crucial addition for managing API rate limits effectively.apps/parser/internal/variables/pubg/lifetime/squad.go (1)
- 30-30: The game mode
SquadFPPMode
is hardcoded. Consider making this configurable to easily extend support for other game modes in the future.apps/parser/internal/types/services/services.go (1)
- 36-36: LGTM! Consider adding documentation for the
PubgClient
field to explain its purpose and usage within the application.apps/parser/internal/variables/pubg/lifetime/duo.go (1)
- 34-34: The game mode
DuoFPPMode
is hardcoded. Consider making this configurable to easily extend support for other game modes in the future.apps/parser/internal/types/variables_cacher.go (1)
- 31-32: LGTM! Consider adding documentation for the new methods
GetPubgLifetimeData
andGetPubgCurrentSeason
to explain their purpose and expected return values.libs/config/src/index.js (1)
- 37-37: LGTM! Consider adding documentation for the
PUBG_API_KEY
configuration parameter to explain its purpose and how to obtain a valid key.frontend/dashboard/src/components/integrations/pubg.vue (1)
- 20-34: Consider adding a loading state to the component to provide feedback to the user during data fetching and updates. This can improve the user experience by indicating that an operation is in progress.
libs/gomodels/integrations.go (1)
- 47-47: The addition of
IntegrationServicePubg
constant is correctly implemented and follows the existing naming convention for integration services. This change is necessary for supporting PUBG integration throughout the application.apps/api/internal/impl_protected/integrations/integrations.go (1)
- 15-15: The addition of the
PubgClient
field to theIntegrations
struct is correctly implemented. This change enables the application to utilize the PUBG client for fetching player statistics. Ensure that thepubg.Client
is properly initialized elsewhere in the application to avoid nil pointer dereferences.frontend/dashboard/src/pages/Integrations.vue (2)
- 12-12: The import of the
Pubg
component is correctly added, following the existing pattern for integrating components. This change is necessary for displaying the PUBG integration option on theIntegrations.vue
page.- 59-61: The addition of the
Pubg
component to the grid layout is correctly implemented, ensuring that PUBG integration is displayed alongside other integrations. This enhances the user interface by providing users with the option to integrate PUBG statistics.apps/parser/internal/cacher/pubg.go (1)
- 13-29: The implementation of
GetPubgCurrentSeason
function correctly fetches and caches the current PUBG season. The use of mutex locks ensures thread safety during cache access and update. This is a good practice for managing shared resources in concurrent environments.apps/parser/internal/cacher/cacher.go (2)
- 31-33: The addition of synchronization mutexes for PUBG data (
pubgLifetimeData
andpubgCurrentSeason
) is correctly implemented. This ensures thread-safe access to PUBG-related cache data, which is crucial for concurrent processing.- 53-55: The introduction of cache structures for PUBG (
pubgLifetimeData
andpubgCurrentSeason
) is correctly done, following the existing pattern for caching game data. This facilitates efficient data retrieval and management for PUBG player statistics.libs/config/config.go (1)
- 49-49: The addition of the
PubgApiKeys
field to theConfig
struct is correctly implemented, allowing the application to support multiple API keys for the PUBG API. This is a crucial feature for managing API rate limits effectively.apps/api/app/app.go (1)
- 135-138: The initialization of the
pubg.Client
using a Redis store is correctly implemented. This setup allows for efficient caching and management of PUBG data, addressing potential API rate limit challenges. Ensure that the Redis client is properly configured and that thePubgApiKeys
are securely managed.apps/parser/internal/variables/pubg/lifetime/solo.go (5)
- 13-41: The implementation of
LifetimeKDSolo
variable and its handler function correctly calculates the K/D ratio for solo game mode. This is a valuable statistic for players, and the calculation method is accurate. Ensure that division by zero is handled appropriately to avoid runtime errors.- 43-71: The
LifetimeWinsSolo
variable and its handler function are correctly implemented to calculate the number of wins in solo game mode. This statistic is straightforward and correctly utilizes the PUBG API data.- 73-101: The
LifetimeMaxKillsSolo
variable correctly calculates the maximum number of kills in a single solo game. This statistic is an interesting metric for players to track their performance. The implementation follows the established pattern and correctly uses the PUBG API data.- 103-131: The
LifetimeWinrateSolo
variable and its handler function correctly calculate the winrate in solo game mode. This is an important statistic for evaluating player performance. Ensure that division by zero is handled to avoid potential runtime errors.- 133-161: The
LifetimeAverageDamageSolo
variable and its handler function correctly calculate the average damage dealt in solo game mode. This statistic provides valuable insight into a player's offensive capabilities. The calculation method is accurate, and division by zero should be handled appropriately.apps/api/internal/impl_protected/impl_protected.go (3)
- 40-40: The import statement for the PUBG client library is correctly added and follows Go's convention for organizing imports alphabetically.
- 88-88: The addition of the
PubgClient
field to theOpts
struct is correctly implemented for dependency injection, following Go's best practices.- 109-109: The modification to include the PUBG client in the
Integrations
struct initialization within theNew
function is correctly implemented.apps/parser/cmd/main.go (2)
- 25-25: The import statement for the PUBG package is correctly added and follows Go's convention for organizing imports alphabetically.
- 152-155: The PUBG client initialization with a Redis store and error handling is correctly implemented. Using
logger.Fatal
for critical errors during initialization is appropriate.libs/pubg/pubg.go (1)
- 1-191: The implementation of the PUBG client library is well-done, with comprehensive error handling, retry logic, and caching mechanism. It correctly manages API keys, rate limiting, and data fetching from the PUBG API.
apps/parser/internal/variables/variables.go (1)
- 127-134: The addition of PUBG lifetime statistics variables to the parser's capabilities is correctly implemented, enhancing the application's ability to handle PUBG-related data.
libs/api/api.proto (2)
- 62-62: The import statement for
integrations_pubg.proto
is correctly added, following the convention for organizing imports in protobuf files.- 144-145: The addition of RPC methods
IntegrationsPubgGet
andIntegrationsPubgPut
to theProtected
service is correctly implemented, enhancing the application's support for PUBG integrations.
|
||
stats := data.Data.Attributes.GameModeStats[pubg.SquadFPPMode] | ||
|
||
result.Result = fmt.Sprintf("%.2f", float64(stats.Kills)/float64(stats.Losses)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a check to ensure stats.Losses
is not zero before performing division to avoid a potential division by zero error.
|
||
stats := data.Data.Attributes.GameModeStats[pubg.DuoFPPMode] | ||
|
||
result.Result = fmt.Sprintf("%.2f", float64(stats.Kills)/float64(stats.Losses)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding a check to ensure stats.Losses
is not zero before performing division to avoid a potential division by zero error.
_, err := db.Query( | ||
`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
"DONATEPAY", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = db.Query( | ||
`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
"VALORANT", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = db.Query(`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, "VALORANT") | ||
_, err = db.Query( | ||
`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
"DONATE_STREAM", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = db.Query(`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, "DONATE_STREAM") | ||
_, err = db.Query( | ||
`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
"DONATELLO", | ||
) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = db.Query(`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, "DONATELLO") | ||
_, err = db.Query( | ||
`INSERT INTO integrations (service) VALUES ($1) ON CONFLICT DO NOTHING`, | ||
"PUBG", | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider refactoring the repetitive insertion queries to use a loop or a batch insertion method. This would improve maintainability and adhere to the DRY principle.
func (c *Integrations) IntegrationsPubgGet( | ||
ctx context.Context, _ *emptypb.Empty, | ||
) (*integrations_pubg.GetDataResponse, error) { | ||
dashboardId := ctx.Value("dashboardId").(string) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider verifying the presence and type of dashboardId
in the context before casting it to a string. This can prevent potential runtime panics if dashboardId
is not present or not a string.
Also applies to: 37-37
@@ -0,0 +1 @@ | |||
package lifetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package is declared as package lifetime
, which seems incorrect given the file's location and purpose (apps/parser/internal/variables/pubg/season/solo.go
). It's likely that the package name should reflect its specific context, such as package season
or a more specific name related to PUBG season statistics for solo play.
@@ -0,0 +1 @@ | |||
package lifetime |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The package is declared as package lifetime
, which seems incorrect given the file's location and purpose (apps/parser/internal/variables/pubg/season/squad.go
). Consider renaming the package to better reflect its specific context, such as package season
or a more specific name related to PUBG season statistics for squad play.
func (c *cacher) GetPubgLifetimeData(ctx context.Context) (*pubg.LifetimeStatsPlayer, error) { | ||
c.locks.pubgLifetimeData.Lock() | ||
defer c.locks.pubgLifetimeData.Unlock() | ||
|
||
if c.cache.pubgLifetimeData != nil { | ||
return c.cache.pubgLifetimeData, nil | ||
} | ||
|
||
c.cache.pubgLifetimeData = &pubg.LifetimeStatsPlayer{} | ||
|
||
if c.cache.pubgCurrentSeason == nil { | ||
_, err := c.GetPubgCurrentSeason(ctx) | ||
if err != nil { | ||
c.services.Logger.Sugar().Error(err) | ||
return nil, err | ||
} | ||
} | ||
|
||
integrations := c.GetEnabledChannelIntegrations(ctx) | ||
|
||
if integrations == nil { | ||
return nil, errors.New("no enabled integrations") | ||
} | ||
|
||
integration, ok := lo.Find( | ||
integrations, func(i *model.ChannelsIntegrations) bool { | ||
return i.Integration.Service == "PUBG" && i.Enabled | ||
}, | ||
) | ||
if !ok { | ||
return nil, errors.New("pubg integration not enabled") | ||
} | ||
|
||
userLifetimeStats, err := c.services.PubgClient.GetLifetimeStats( | ||
ctx, | ||
lo.FromPtr(integration.Data.UserId), | ||
) | ||
if err != nil { | ||
if errors.Is(err, tpubg.ErrOverloaded) { | ||
return nil, tpubg.ErrOverloaded | ||
} | ||
if errors.Is(err, tpubg.ErrPubg) { | ||
return nil, tpubg.ErrPubg | ||
} | ||
|
||
c.services.Logger.Sugar().Error(err) | ||
return nil, errors.Unwrap(err) | ||
} | ||
c.cache.pubgLifetimeData = userLifetimeStats | ||
|
||
return c.cache.pubgLifetimeData, nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The GetPubgLifetimeData
function correctly fetches and caches PUBG player lifetime stats. It demonstrates proper error handling and logging, and efficiently reuses the GetPubgCurrentSeason
function to ensure the current season is available. Consider adding more detailed error messages to improve debugging and user feedback.
- result.Result = err.Error()
+ result.Result = "Failed to fetch PUBG lifetime data: " + err.Error()
Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.
func (c *cacher) GetPubgLifetimeData(ctx context.Context) (*pubg.LifetimeStatsPlayer, error) { | |
c.locks.pubgLifetimeData.Lock() | |
defer c.locks.pubgLifetimeData.Unlock() | |
if c.cache.pubgLifetimeData != nil { | |
return c.cache.pubgLifetimeData, nil | |
} | |
c.cache.pubgLifetimeData = &pubg.LifetimeStatsPlayer{} | |
if c.cache.pubgCurrentSeason == nil { | |
_, err := c.GetPubgCurrentSeason(ctx) | |
if err != nil { | |
c.services.Logger.Sugar().Error(err) | |
return nil, err | |
} | |
} | |
integrations := c.GetEnabledChannelIntegrations(ctx) | |
if integrations == nil { | |
return nil, errors.New("no enabled integrations") | |
} | |
integration, ok := lo.Find( | |
integrations, func(i *model.ChannelsIntegrations) bool { | |
return i.Integration.Service == "PUBG" && i.Enabled | |
}, | |
) | |
if !ok { | |
return nil, errors.New("pubg integration not enabled") | |
} | |
userLifetimeStats, err := c.services.PubgClient.GetLifetimeStats( | |
ctx, | |
lo.FromPtr(integration.Data.UserId), | |
) | |
if err != nil { | |
if errors.Is(err, tpubg.ErrOverloaded) { | |
return nil, tpubg.ErrOverloaded | |
} | |
if errors.Is(err, tpubg.ErrPubg) { | |
return nil, tpubg.ErrPubg | |
} | |
c.services.Logger.Sugar().Error(err) | |
return nil, errors.Unwrap(err) | |
} | |
c.cache.pubgLifetimeData = userLifetimeStats | |
return c.cache.pubgLifetimeData, nil | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Review Status
Configuration used: CodeRabbit UI
Files ignored due to path filters (5)
apps/api/go.mod
is excluded by!**/*.mod
,!**/*.mod
apps/api/go.sum
is excluded by!**/*.sum
,!**/*.sum
apps/parser/go.mod
is excluded by!**/*.mod
,!**/*.mod
frontend/dashboard/src/locales/en.json
is excluded by!**/*.json
go.work.sum
is excluded by!**/*.sum
,!**/*.sum
Files selected for processing (5)
- apps/parser/internal/variables/variables.go (2 hunks)
- frontend/dashboard/src/api/integrations/index.ts (1 hunks)
- libs/api/api.proto (2 hunks)
- libs/gomodels/integrations.go (1 hunks)
- libs/migrations/seeds/integrations.go (1 hunks)
Additional Context Used
Additional comments not posted (6)
frontend/dashboard/src/api/integrations/index.ts (1)
6-6
: The addition ofexport * from './pubg.js';
aligns with the existing pattern for exporting integration modules. Ensure thatpubg.js
is correctly implemented and tested.libs/migrations/seeds/integrations.go (1)
51-57
: Consider refactoring the repetitive insertion queries to use a loop or a batch insertion method. This would improve maintainability and adhere to the DRY principle. For now, the addition of the "PUBG" integration record is consistent with the existing pattern.libs/gomodels/integrations.go (1)
47-48
: The addition ofIntegrationServicePubg
constant aligns with the existing pattern for defining integration services. Ensure that this new constant is correctly used wherever integration services are handled in the project.apps/parser/internal/variables/variables.go (1)
128-135
: The addition of PUBG lifetime variables aligns with the existing pattern for defining and adding variables. Ensure that these variables are correctly implemented and tested in their respective files.libs/api/api.proto (2)
63-63
: The addition ofimport "messages/integrations_pubg/integrations_pubg.proto";
aligns with the existing pattern for extending the API with new integrations. Ensure that theintegrations_pubg.proto
file is correctly implemented and tested.
152-153
: The addition ofIntegrationsPubgGet
andIntegrationsPubgPut
RPC methods is consistent with the project's approach to extending the API. Ensure that these methods are correctly implemented and tested in the backend.
During watching PUBG pro players streams I realized that tons of people asking about their stats, so I decided to add integration with API. It has low limits (10 per minutes but response is complex) that's why I implemented support of multiple api keys and good ttl caching. Also PUBG is ready to expand limits.
The problem is that PUBG needs probably 30 variables about stats and it's to much for one game and only few is really needed. So, I just implemented some of them for testing purposes. Plus, there is maybe too complicated to create right command to show statistic and probably we need to provide default command for it.
Of course, I'm ready to give my api key for production.
Summary by CodeRabbit
New Features
Enhancements
Documentation
PUBG_API_KEYS
.Database Changes
Bug Fixes