Skip to content

Commit b7e81db

Browse files
authored
Merge pull request #15 from ScrappyCocco/developjson
New version of the API parsing the JSON
2 parents ca6ae96 + fea85a8 commit b7e81db

17 files changed

+522
-452
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# This workflows will test the dev version of the API when pushed on github
2+
3+
name: Python Test Github Dev Version
4+
5+
on:
6+
[push, pull_request, discussion, issues]
7+
8+
jobs:
9+
test:
10+
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v2
15+
with:
16+
# Disabling shallow clone is recommended for improving relevancy of reporting
17+
fetch-depth: 0
18+
- name: Set up Python
19+
uses: actions/setup-python@v2
20+
with:
21+
python-version: '3.6'
22+
- name: Install dependencies
23+
run: |
24+
cd howlongtobeatpy
25+
python -m pip install --upgrade pip
26+
pip install nose codecov
27+
pip install .
28+
- name: Test
29+
run: |
30+
nosetests howlongtobeatpy --with-coverage
31+
coverage xml
32+
- name: Upload Coverage codecov
33+
env:
34+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
36+
run: |
37+
codecov
38+
- name: SonarCloud Scan
39+
uses: sonarsource/sonarcloud-github-action@master
40+
env:
41+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
1-
# This workflows will upload a Python Package using Twine when a release is created
2-
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
1+
# This workflows will test the released version of the API
32

4-
name: Python Test
3+
name: Python Test Released Published Version
54

65
on:
7-
push:
8-
branches:
9-
- master
10-
pull_request:
11-
types: [opened, synchronize, reopened]
12-
branches: [ master ]
136
release:
147
types: [created, edited]
158
schedule:

.gitignore

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,6 @@ howlongtobeatpy/howlongtobeatpy/__pycache__/
99

1010
howlongtobeatpy/howlongtobeatpy\.egg-info/
1111

12-
howlongtobeatpy/LICENSE\.md
13-
14-
howlongtobeatpy/README\.md
15-
1612
\.scannerwork/
1713

1814
howlongtobeatpy/tests/test_normal_request_debug\.py

README.md

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# HowLongToBeat Python API
2+
23
[![Python Test](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/python-test.yml/badge.svg)](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/python-test.yml)
34
[![CodeQL](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/codeql-analysis.yml)
45

@@ -10,20 +11,21 @@ A simple Python API to read data from howlongtobeat.com.
1011
It is inspired by [ckatzorke - howlongtobeat](https://github.com/ckatzorke/howlongtobeat) JS API.
1112

1213
## Content
13-
- [Usage](#usage)
14-
- [Installation](#installation)
15-
- [Installing the package downloading the last release](#installing-the-package-downloading-the-last-release)
16-
- [Installing the package from the source code](#installing-the-package-from-the-source-code)
17-
- [Usage in code](#usage-in-code)
18-
- [Start including it in your file](#start-including-it-in-your-file)
19-
- [Now call search()](#now-call-search)
20-
- [Alternative search (by id)](#alternative-search-by-id)
21-
- [DLC search](#dlc-search)
22-
- [Results auto-filter](#results-auto-filter)
23-
- [Reading an entry](#reading-an-entry)
24-
- [Found a bug?](#found-a-bug)
25-
- [Authors](#authors)
26-
- [License](#license)
14+
15+
- [Usage](#usage)
16+
- [Installation](#installation)
17+
- [Installing the package downloading the last release](#installing-the-package-downloading-the-last-release)
18+
- [Installing the package from the source code](#installing-the-package-from-the-source-code)
19+
- [Usage in code](#usage-in-code)
20+
- [Start including it in your file](#start-including-it-in-your-file)
21+
- [Now call search()](#now-call-search)
22+
- [Alternative search (by ID)](#alternative-search-by-id)
23+
- [DLC search](#dlc-search)
24+
- [Results auto-filter](#results-auto-filter)
25+
- [Reading an entry](#reading-an-entry)
26+
- [Issues, Questions & Discussions](#issues-questions--discussions)
27+
- [Authors](#authors)
28+
- [License](#license)
2729

2830
## Usage
2931

@@ -78,14 +80,13 @@ if results_list is not None and len(results_list) > 0:
7880
Once done, "best_element" will contain the best game found in the research.
7981
Every entry in the list (if not None in case of errors) is an object of type: [HowLongToBeatEntry](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py).
8082

81-
### Alternative search (by id)
83+
### Alternative search (by ID)
8284

83-
If you prefer, you can get a game by id, this can be useful if you already have the game's howlongtobeat-id.
84-
Unluckily, is not worth to make a parser for the single-page game info, because is a user page that can change frequently and full of HTML.
85+
If you prefer, you can get a game by ID, this can be useful if you already have the game's howlongtobeat-id (the ID is the number in the URL, for example in [https://howlongtobeat.com/game/7231]([hello](https://howlongtobeat.com/game/7231)) the ID is 7231).
8586

86-
To avoid a new parser, the search by id use a first request to get the game title, and then use the standard search, filtering the results and returning the unique game with that id.
87+
To avoid a new parser, the search by ID use a first request to get the game title, and then use the standard search with that title, filtering the results and returning the unique game with that ID.
8788

88-
Remember that it could be a bit slower, but you avoid searching the game in the array.
89+
Remember that it could be a bit slower, but you avoid searching the game in the array by similarity.
8990

9091
Here's the example:
9192

@@ -102,21 +103,19 @@ result = await HowLongToBeat().async_search_from_id(123456)
102103
This call will return an unique [HowLongToBeatEntry](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py) or None in case of errors.
103104

104105
### DLC search
105-
Apparently in the default search DLCs don't appear (see: [#6](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/issues/6)). An `enum` has been added:
106+
107+
An `enum` has been added to have a filter in the search:
106108

107109
```python
108-
SearchModifiers.NONE
109-
SearchModifiers.INCLUDE_DLC # Probably unnecessary
110+
SearchModifiers.NONE # default
110111
SearchModifiers.ISOLATE_DLC
111112
SearchModifiers.HIDE_DLC
112113
```
113114

114-
This optional parameter allow you to specify in the search if you want the default search (no DLCs), to INCLUDE DLCs along with games, or to ISOLATE DLCs (show only DLCs in the result).
115-
116-
**Update January 2020**: Apparently HowLongToBeat re-added DLCs in the default search, so `SearchModifiers.INCLUDE_DLC` should no longer be necessary. It will remain for completeness and compatibility.
117-
A new option has been added instead: `SearchModifiers.HIDE_DLC`, that is basically the opposite of including DLCs.
115+
This optional parameter allow you to specify in the search if you want the default search (with DLCs), to HIDE DLCs and only show games, or to ISOLATE DLCs (show only DLCs).
118116

119117
### Results auto-filter
118+
120119
To ignore games with a very different name, the standard search automatically filter results with a game name that has a similarity with the given name > than `0.4`, not adding the others to the result list.
121120
If you want all the results, or you want to change this value, you can put a parameter in the constructor:
122121

@@ -132,21 +131,21 @@ Also remember that by default the similarity check **is case-sensitive** between
132131
results = HowLongToBeat(0.0).search("Awesome Game", similarity_case_sensitive=False)
133132
```
134133

135-
**Remember** that, when searching by ID, the similarity value and the case-sensitive bool are ignored.
134+
**Remember** that, when searching by ID, the similarity value and the case-sensitive bool are **ignored**.
136135

137136
### Reading an entry
138137

139-
An entry is made of few values, you can check them [in the Entry class file](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py)
138+
An entry is made of few values, you can check them [in the Entry class file](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py). It also include the full JSON of values (already converted to Python dict) received from HLTB.
140139

141140
## Issues, Questions & Discussions
142141

143142
If you found a bug report it as soon as you can creating an [issue](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/issues/new), the code may not be perfect.
144143

145-
If you need any new feature, or want to discuss the current implementation/features, consider opening a [discussion](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/discussions).
144+
If you need any new feature, or want to discuss the current implementation/features, consider opening a [discussion](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/discussions) or even propose a change with a [Pull Request](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/pulls).
146145

147146
## Authors
148147

149-
* **ScrappyCocco**
148+
* **ScrappyCocco** - Thank you for using my API
150149

151150
## License
152151

howlongtobeatpy/LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Michele
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

howlongtobeatpy/README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# HowLongToBeat Python API
2+
3+
[![Python Test](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/python-test.yml/badge.svg)](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/python-test.yml)
4+
[![CodeQL](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/actions/workflows/codeql-analysis.yml)
5+
6+
[![codecov](https://codecov.io/gh/ScrappyCocco/HowLongToBeat-PythonAPI/branch/master/graph/badge.svg)](https://codecov.io/gh/ScrappyCocco/HowLongToBeat-PythonAPI)
7+
[![Bugs](https://sonarcloud.io/api/project_badges/measure?project=ScrappyCocco_HowLongToBeat-PythonAPI&metric=bugs)](https://sonarcloud.io/dashboard?id=ScrappyCocco_HowLongToBeat-PythonAPI)
8+
9+
A simple Python API to read data from howlongtobeat.com.
10+
11+
It is inspired by [ckatzorke - howlongtobeat](https://github.com/ckatzorke/howlongtobeat) JS API.
12+
13+
## Content
14+
15+
- [Usage](#usage)
16+
- [Installation](#installation)
17+
- [Installing the package downloading the last release](#installing-the-package-downloading-the-last-release)
18+
- [Installing the package from the source code](#installing-the-package-from-the-source-code)
19+
- [Usage in code](#usage-in-code)
20+
- [Start including it in your file](#start-including-it-in-your-file)
21+
- [Now call search()](#now-call-search)
22+
- [Alternative search (by ID)](#alternative-search-by-id)
23+
- [DLC search](#dlc-search)
24+
- [Results auto-filter](#results-auto-filter)
25+
- [Reading an entry](#reading-an-entry)
26+
- [Issues, Questions & Discussions](#issues-questions--discussions)
27+
- [Authors](#authors)
28+
- [License](#license)
29+
30+
## Usage
31+
32+
## Installation
33+
34+
### Installing the package downloading the last release
35+
36+
```python
37+
pip install howlongtobeatpy
38+
```
39+
40+
### Installing the package from the source code
41+
42+
Download the repo, enter the folder with 'setup.py' and run the command
43+
44+
```python
45+
pip install .
46+
```
47+
48+
## Usage in code
49+
50+
### Start including it in your file
51+
52+
```python
53+
from howlongtobeatpy import HowLongToBeat
54+
```
55+
56+
### Now call search()
57+
58+
The API main functions are:
59+
60+
```python
61+
results = HowLongToBeat().search("Awesome Game")
62+
```
63+
64+
or, if you prefer using async:
65+
66+
```python
67+
results = await HowLongToBeat().async_search("Awesome Game")
68+
```
69+
70+
The return of that function is a **list** of possible games, or **None** in case you passed an invalid "game name" as parameter or if there was an error in the request.
71+
72+
If the list **is not None** you should choose the best entry checking the Similarity value with the original name, example:
73+
74+
```python
75+
results_list = await HowLongToBeat().async_search("Awesome Game")
76+
if results_list is not None and len(results_list) > 0:
77+
best_element = max(results_list, key=lambda element: element.similarity)
78+
```
79+
80+
Once done, "best_element" will contain the best game found in the research.
81+
Every entry in the list (if not None in case of errors) is an object of type: [HowLongToBeatEntry](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py).
82+
83+
### Alternative search (by ID)
84+
85+
If you prefer, you can get a game by ID, this can be useful if you already have the game's howlongtobeat-id (the ID is the number in the URL, for example in [https://howlongtobeat.com/game/7231]([hello](https://howlongtobeat.com/game/7231)) the ID is 7231).
86+
87+
To avoid a new parser, the search by ID use a first request to get the game title, and then use the standard search with that title, filtering the results and returning the unique game with that ID.
88+
89+
Remember that it could be a bit slower, but you avoid searching the game in the array by similarity.
90+
91+
Here's the example:
92+
93+
```python
94+
result = HowLongToBeat().search_from_id(123456)
95+
```
96+
97+
or, if you prefer using async:
98+
99+
```python
100+
result = await HowLongToBeat().async_search_from_id(123456)
101+
```
102+
103+
This call will return an unique [HowLongToBeatEntry](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py) or None in case of errors.
104+
105+
### DLC search
106+
107+
An `enum` has been added to have a filter in the search:
108+
109+
```python
110+
SearchModifiers.NONE # default
111+
SearchModifiers.ISOLATE_DLC
112+
SearchModifiers.HIDE_DLC
113+
```
114+
115+
This optional parameter allow you to specify in the search if you want the default search (with DLCs), to HIDE DLCs and only show games, or to ISOLATE DLCs (show only DLCs).
116+
117+
### Results auto-filter
118+
119+
To ignore games with a very different name, the standard search automatically filter results with a game name that has a similarity with the given name > than `0.4`, not adding the others to the result list.
120+
If you want all the results, or you want to change this value, you can put a parameter in the constructor:
121+
122+
```python
123+
results = HowLongToBeat(0.0).search("Awesome Game")
124+
```
125+
126+
putting `0.0` (or just `0`) will return all the found games, otherwise you can write another (`float`) number between 0...1 to set a new filter, such as `0.7`.
127+
128+
Also remember that by default the similarity check **is case-sensitive** between the name given and the name found, if you want to ignore the case you can use:
129+
130+
```python
131+
results = HowLongToBeat(0.0).search("Awesome Game", similarity_case_sensitive=False)
132+
```
133+
134+
**Remember** that, when searching by ID, the similarity value and the case-sensitive bool are **ignored**.
135+
136+
### Reading an entry
137+
138+
An entry is made of few values, you can check them [in the Entry class file](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/blob/master/howlongtobeatpy/howlongtobeatpy/HowLongToBeatEntry.py). It also include the full JSON of values (already converted to Python dict) received from HLTB.
139+
140+
## Issues, Questions & Discussions
141+
142+
If you found a bug report it as soon as you can creating an [issue](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/issues/new), the code may not be perfect.
143+
144+
If you need any new feature, or want to discuss the current implementation/features, consider opening a [discussion](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/discussions) or even propose a change with a [Pull Request](https://github.com/ScrappyCocco/HowLongToBeat-PythonAPI/pulls).
145+
146+
## Authors
147+
148+
* **ScrappyCocco** - Thank you for using my API
149+
150+
## License
151+
152+
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details

0 commit comments

Comments
 (0)