Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

✨ feat: captchas can be resolved by user #4

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
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: 1 addition & 1 deletion .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ jobs:
pip install -r requirements.txt
- name: Analysing the code with pylint
run: |
pylint `git ls-files|grep .py$|xargs` --fail-under=8.5
pylint `git ls-files|grep .py$|xargs` --fail-under=9.01 --max-line-length=130
if: always()

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/.idea/
/TGVmax.iml
.env
__pycache__/
__pycache__/
/TGV_Maximize.iml
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
Create and fill a `.env` file with your cookies content.
<details>
<summary><b>Follow</b> this tutorial to get your <code>sncf-connect.com</code> cookies. Reproduce it once you are connected to your account.
<i>Altough the website presented is the old <code>oui.sncf</code>, it still working on <code>sncf-Connect.com</code></i></summary>
<i>Although the website presented is the old <code>oui.sncf</code>, it's still working on <code>sncf-Connect.com</code></i></summary>

![](docs/get-ouisncf-cookies-tutorial.gif)

Expand Down
14 changes: 0 additions & 14 deletions bcolors.py

This file was deleted.

27 changes: 27 additions & 0 deletions captcha.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
"""
Captcha resolver related code
"""
from json import loads
from seleniumwire import webdriver

def resolve(captcha_url: str) -> str:
"""
Open a browser window the user and navigate to the URL provided.
Return cookie provided on captcha successfully
:param captcha_url: url to navigate to
:return:
"""
print("A window will be opened with a captcha. Resolve it and come back in the script")
web_browser = webdriver.Firefox()
web_browser.get(captcha_url) # Navigate to this url
print("Press enter if you resolved successfully the captcha. Instead, please exit the script")
input()
datadome = None
for request_sent in web_browser.requests:
if request_sent.url.startswith('https://geo.captcha-delivery.com/captcha/check'):
json_datadome = request_sent.response.body
datadome = loads(json_datadome)
print(datadome['cookie'].split(';')[0])
if datadome is not None:
return datadome['cookie'].split(';')[0]
raise ValueError('Captcha has not been successfully resolved')
27 changes: 26 additions & 1 deletion config.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
"""
Code related to .env config
"""
import os
from typing import get_type_hints, Union

from dotenv import load_dotenv
from dotenv import load_dotenv,set_key

load_dotenv()

def dict_cookie_from_str(str_cookies):
d_cookies = {}
l_cookies = str_cookies.split("; ")
for key_item in l_cookies:
i = key_item.find("=")
key = key_item[:i]
item = key_item[i+1:]
d_cookies[key] = item
return d_cookies

def str_cookies_from_dict(d_cookies):
str_cookie = ""
for key, item in d_cookies.items():
str_cookie += key + "="+ item + "; "
str_cookie = str_cookie[:-2]
return str_cookie

class AppConfigError(Exception):
"""
Expand Down Expand Up @@ -57,6 +76,12 @@ def __init__(self, env):
def __repr__(self):
return str(self.__dict__)

@staticmethod
def update_cookies_from_dict(field, str_cookies):
set_key('.env',field, str_cookies)
print('new cookie added to .env:', str_cookies)



# Expose Config object for app to import
Config = AppConfig(os.environ)
11 changes: 7 additions & 4 deletions direct_destination.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
"""
Code related to direct destinations accessible from train station
"""
from operator import itemgetter
from requests import get, Response as ReqResponse

Expand Down Expand Up @@ -39,9 +42,9 @@ def parse(station: Station, request: ReqResponse):
def get_common_stations(departure_direct_destinations: 'DirectDestination',
arrival_direct_destinations: 'DirectDestination') -> [Station]:
"""
Returns a list of stations that are common to both the departure and arrival stations.
:param departure_direct_destinations: The departure station's direct destinations.
:param arrival_direct_destinations: The arrival station's direct destinations.
Returns a list of stations that are common to both the departure and arrival stations
:param departure_direct_destinations: The departure station's direct destinations
:param arrival_direct_destinations: The arrival station's direct destinations
:return: A list of stations
"""

Expand All @@ -59,7 +62,7 @@ def get(departure: Station):
"""
Returns the direct destinations of a given station.
"""
response = get('https://api.direkt.bahn.guru/' + departure.identifier)
response = get('https://api.direkt.bahn.guru/' + departure.identifier, timeout=15)
if response.status_code != 200:
print()
raise ValueError(f'{departure.name} identifier not found is UIC database.'
Expand Down
19 changes: 10 additions & 9 deletions docs/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> #### Le but de cet outil est de permettre de trouver les trajets TGVmax disponibles entre deux villes.
>#### Il est possible de choisir le nombre de trajets à afficher et de choisir la date de départ ainsi que le nombre de jours à afficher.
>#### A terme, il sera possible de trouver les trajets TGVmax entre deux villes en intégrant le découpage du trajet, afin de maximiser les chances de trouver un trajet même lors des périodes de forte affluences.
>#### À terme, il sera possible de trouver les trajets TGVmax entre deux villes en intégrant le découpage du trajet, afin de maximiser les chances de trouver un trajet même lors des périodes de forte affluences.

## Méthodes pour récupérer les trajets directs

Expand All @@ -16,17 +16,18 @@ l'étape la plus rapide et la plus facile à réaliser.
## Trajets indirects : la grande inconnue

Cependant, il n'était pas possible de récupérer les trajets qui comprenaient une ou plusieurs correspondances. J'ai donc
du trouver une méthode pour récupérer les trajets avec correspondances tout en prenant en compte qu'il fallait parfois
trouver une méthode pour récupérer les trajets avec correspondances tout en prenant en compte qu'il fallait parfois
provoquer volontairement celles-ci lorsque les trains directs sont complets et que l'on souhaite découper son trajet. De
plus, il fallait tenir compte que les trajets proposés en correspondances étaient susceptibles d'être à bord de TERs (
Trains Express Régionaux) qui ne sont pas éligibles à TGVmax. J'ai d'abord cherché les moyens d'obtenir les gares
plus, il fallait tenir compte que les trajets proposés en correspondances étaient susceptibles d'être à bord de TERs
(Trains Express Régionaux) qui ne sont pas éligibles à TGVmax. J'ai d'abord cherché les moyens d'obtenir les gares
intermédiaires communes entre les deux gares. J'étais déjà tombé sur l'outil direkt.bahn.guru qui permet d'afficher sur
une carte intéractive l'ensemble des destinations atteignables à partir d'une gare.
![Aperçu de l'outil https://direkt.bahn.guru/ qui affiche ici toutes les destinations accesibles depuis Paris Gare de Lyon](img.png)
une carte interactive l'ensemble des destinations atteignables à partir d'une gare.
![Aperçu de l'outil https://direkt.bahn.guru/ qui affiche ici toutes les destinations accessible depuis Paris Gare de Lyon](img.png)

#### https://direkt.bahn.guru/?origin=8700012

Après un reverse-engineering, j'ai identifié l'API utilisé pour obtenir les gares atteignables. Contre toute attente, la
base de données utilisée provennait de HAFAS, un logiciel de calcul d'itinéraire. Le données quant à elles sont celles
de la Deutsche Bahn, l'entreprise ferroviaire publique allemande, qui as accès à la base de données des circulations ferroviaire en France.
Après une retro-ingénierie, j'ai identifié l'API utilisé pour obtenir les gares atteignables. Contre toute attente, la
base de données utilisée provenait de HAFAS, un logiciel de calcul d'itinéraire. Les données quant à elles sont celles
de la Deutsche Bahn, l'entreprise ferroviaire publique allemande, qui a accès à la base de données des gares
ferroviaires en France.

Loading