Giter VIP home page Giter VIP logo

api's Introduction

salmon-stats-api

Overview

Installation

git clone https://github.com/yukidaruma/salmon-stats
docker-compose build

cp example.env .env
# Update .env if necessary.
# You must provide Twitter API key in order to use login with Twitter feature.
vi .env

docker-compose exec app bash
composer install --no-dev # TODO: move `composer install` to Dockerfile
php artisan key:generate
php artisan migrate

# Fetch past Salmon Run schedules
php artisan salmon-stats:fetch-schedules

# Add **host** crontab
* * * * * php /{path_to_project}/artisan schedule:run >> /dev/null 2>&1

Running tests

docker-compose exec app vendor/bin/phpunit

Start

docker-compose up -d

Third-party APIs

This app is using following third-party APIs.

api's People

Contributors

dependabot[bot] avatar yukidaruma avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

api's Issues

feat: Add ability to override redirect url after signing into Twitter

This change is required for tkgstrator/Salmonia2#14.

  • https://salmon-stats-api.yuki.games/auth/twitter?redirect_to=<...>
    • Allow list is defined in services.twitter config
      • The first entry will be used as default redirect URL
    • If a request does not have parameter redirect_to or specified redirect URL is not in allow list, default redirect URL will be used

Test cases

  • If the specified redirect url is not included in allow list, the default redirect URL will be used.
  • It can redirect to local dev environment.
  • It can redirect to production environment.

Provide `Access-Control-Allow-Origin` header to use CORS

image

フロントエンドとAPIが別ドメインで運用されているため、APIのリクエストがブロックされています。
API requests are blocked because the domains for the frontend and the API are different.
XHRのOriginヘッダを見て、適切(本番の場合salmon-stats.yuki.games)ならばAccess-Control-Allow-Originヘッダにそのまま埋め込むようにすれば、サイト内のAPIリクエストが正常に処理されるかと思います。
API requests in the website will be successfully processed if the API check the contents of the Origin header in API requests and copy them to the Access-Control-Allow-Origin header if there is no problem there (salmon-stats.yuki.games in production).

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Origin
https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

Add ability to fetch raw results of player

/api/players/:id/results?raw=1[&count=100][&page=1]

Parameters Description
raw Required
page for pagination
count 1 to 200 (default: 100)

Example response

// 20200802190803
// http://localhost/api/players/2cf69d9715b323b7/results?raw=1&count=1

{
  "current_page": 1,
  "first_page_url": "http://localhost/api/players/2cf69d9715b323b7/results?page=1",
  "from": 1,
  "next_page_url": "http://localhost/api/players/2cf69d9715b323b7/results?page=2",
  "path": "http://localhost/api/players/2cf69d9715b323b7/results",
  "per_page": 1,
  "prev_page_url": null,
  "to": 1,
  "results": [
    {
      "id": 249569,
      "schedule_id": "2020-06-19 06:00:00",
      "start_at": "2020-06-20 17:50:49",
      "members": [
        "2cf69d9715b323b7",
        "5953558f15cb449a",
        "b263b48b94964ca8",
        "f99ded5e4e3d6aa7"
      ],
      "boss_appearances": {
        "3": 0,
        "6": 7,
        "9": 7,
        "12": 5,
        "13": 7,
        "14": 8,
        "15": 11,
        "16": 0,
        "21": 9
      },
      "uploader_user_id": 2,
      "clear_waves": 3,
      "fail_reason_id": null,
      "danger_rate": "166.4",
      "created_at": "2020-06-20T18:10:12.000000Z",
      "updated_at": "2020-06-20T18:10:12.000000Z",
      "golden_egg_delivered": 65,
      "power_egg_collected": 2848,
      "boss_appearance_count": 54,
      "boss_elimination_count": 43,
      "is_eligible_for_no_night_record": true,
      "player_results": [
        {
          "player_id": "2cf69d9715b323b7",
          "golden_eggs": 16,
          "power_eggs": 948,
          "rescue": 5,
          "death": 7,
          "special_id": 2,
          "boss_elimination_count": 10,
          "grade_point": 810,
          "boss_eliminations": {
            "counts": {
              "3": 0,
              "6": 1,
              "9": 0,
              "12": 1,
              "13": 0,
              "14": 4,
              "15": 2,
              "16": 0,
              "21": 2
            }
          },
          "weapons": [
            {
              "weapon_id": 240
            },
            {
              "weapon_id": 30
            },
            {
              "weapon_id": 4010
            }
          ],
          "special_uses": [
            {
              "count": 0
            },
            {
              "count": 1
            },
            {
              "count": 1
            }
          ]
        },
        {
          "player_id": "5953558f15cb449a",
          "golden_eggs": 18,
          "power_eggs": 576,
          "rescue": 5,
          "death": 7,
          "special_id": 9,
          "boss_elimination_count": 10,
          "grade_point": null,
          "boss_eliminations": {
            "counts": {
              "3": 0,
              "6": 3,
              "9": 0,
              "12": 1,
              "13": 3,
              "14": 0,
              "15": 2,
              "16": 0,
              "21": 1
            }
          },
          "weapons": [
            {
              "weapon_id": 5040
            },
            {
              "weapon_id": 4010
            },
            {
              "weapon_id": 30
            }
          ],
          "special_uses": [
            {
              "count": 1
            },
            {
              "count": 0
            },
            {
              "count": 1
            }
          ]
        },
        {
          "player_id": "b263b48b94964ca8",
          "golden_eggs": 11,
          "power_eggs": 622,
          "rescue": 3,
          "death": 6,
          "special_id": 7,
          "boss_elimination_count": 9,
          "grade_point": null,
          "boss_eliminations": {
            "counts": {
              "3": 0,
              "6": 0,
              "9": 0,
              "12": 3,
              "13": 1,
              "14": 1,
              "15": 3,
              "16": 0,
              "21": 1
            }
          },
          "weapons": [
            {
              "weapon_id": 4010
            },
            {
              "weapon_id": 240
            },
            {
              "weapon_id": 5040
            }
          ],
          "special_uses": [
            {
              "count": 1
            },
            {
              "count": 1
            },
            {
              "count": 0
            }
          ]
        },
        {
          "player_id": "f99ded5e4e3d6aa7",
          "golden_eggs": 20,
          "power_eggs": 702,
          "rescue": 11,
          "death": 4,
          "special_id": 8,
          "boss_elimination_count": 14,
          "grade_point": null,
          "boss_eliminations": {
            "counts": {
              "3": 0,
              "6": 3,
              "9": 2,
              "12": 0,
              "13": 2,
              "14": 2,
              "15": 3,
              "16": 0,
              "21": 2
            }
          },
          "weapons": [
            {
              "weapon_id": 30
            },
            {
              "weapon_id": 5040
            },
            {
              "weapon_id": 240
            }
          ],
          "special_uses": [
            {
              "count": 0
            },
            {
              "count": 0
            },
            {
              "count": 2
            }
          ]
        }
      ],
      "waves": [
        {
          "wave": 1,
          "event_id": 0,
          "water_id": 3,
          "golden_egg_quota": 18,
          "golden_egg_appearances": 39,
          "golden_egg_delivered": 20,
          "power_egg_collected": 934
        },
        {
          "wave": 2,
          "event_id": 0,
          "water_id": 3,
          "golden_egg_quota": 19,
          "golden_egg_appearances": 45,
          "golden_egg_delivered": 24,
          "power_egg_collected": 995
        },
        {
          "wave": 3,
          "event_id": 0,
          "water_id": 3,
          "golden_egg_quota": 21,
          "golden_egg_appearances": 45,
          "golden_egg_delivered": 21,
          "power_egg_collected": 919
        }
      ]
    }
  ]
}```

Fix error when no results were uploaded

[2020-03-13 08:10:55] production.ERROR: Undefined variable: results
{"userId":redacted,"exception":"[object] (ErrorException(code: 0): Undefined variable: results at /var/www/html/app/Http/Controllers/SalmonResultController.php:274)

[2020-03-13 10:35:07] production.ERROR: Undefined variable: results
{"userId":redacted,"exception":"[object] (ErrorException(code: 0): Undefined variable: results at /var/www/html/app/Http/Controllers/SalmonResultController.php:274)

[2020-03-13 15:27:42] production.ERROR: Undefined variable: results
{"userId":redacted,"exception":"[object] (ErrorException(code: 0): Undefined variable: results at /var/www/html/app/Http/Controllers/SalmonResultController.php:274)

Improve performance of `results.show`

The following query alone took 800ms+.

select * from `salmon_player_weapons` where
  ((`salmon_player_weapons`.`salmon_id` = 249569 and `salmon_player_weapons`.`player_id` = '2cf69d9715b323b7') or (`salmon_player_weapons`.`salmon_id` = 249569 and `salmon_player_weapons`.`player_id` = '5953558f15cb449a') or (`salmon_player_weapons`.`salmon_id` = 249569 and `salmon_player_weapons`.`player_id` = 'b263b48b94964ca8') or (`salmon_player_weapons`.`salmon_id` = 249569 and `salmon_player_weapons`.`player_id` = 'f99ded5e4e3d6aa7')) 
  order by `wave` asc
class SalmonResult extends Model
{
    // ...

    public function playerResults()
    {
        return $this
            ->hasMany('App\SalmonPlayerResult', 'salmon_id')
            ->with(['bossEliminations', 'specialUses', 'weapons']);
    }

This query becomes slower as more results are uploaded. (specifically speaking, number of salmon_player_weapons rows involves.)

Benchmark before optimization ``` hey -n 10 -c 1 http://localhost/api/results/249569

Summary:
Total: 15.4258 secs
Slowest: 1.7445 secs
Fastest: 1.4940 secs
Average: 1.5426 secs
Requests/sec: 0.6483

Response time histogram:
1.494 [1] |■■■■■■■■■■
1.519 [4] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1.544 [3] |■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
1.569 [1] |■■■■■■■■■■
1.594 [0] |
1.619 [0] |
1.644 [0] |
1.669 [0] |
1.694 [0] |
1.719 [0] |
1.745 [1] |■■■■■■■■■■

Latency distribution:
10% in 1.5054 secs
25% in 1.5121 secs
50% in 1.5214 secs
75% in 1.5544 secs
90% in 1.7445 secs
0% in 0.0000 secs
0% in 0.0000 secs

Details (average, fastest, slowest):
DNS+dialup: 0.0004 secs, 1.4940 secs, 1.7445 secs
DNS-lookup: 0.0003 secs, 0.0000 secs, 0.0029 secs
req write: 0.0000 secs, 0.0000 secs, 0.0001 secs
resp wait: 1.5420 secs, 1.4937 secs, 1.7400 secs
resp read: 0.0001 secs, 0.0001 secs, 0.0002 secs

Status code distribution:
[200] 10 responses

</details>

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.