MrSimple07 commited on
Commit
a25bdd2
·
1 Parent(s): 3d08d61

new fetch lichess puzzle

Browse files
Files changed (1) hide show
  1. core/chess_api.py +84 -30
core/chess_api.py CHANGED
@@ -54,41 +54,95 @@ def get_user_games_from_chess_com(username):
54
 
55
 
56
  def fetch_lichess_puzzles(error_types, user_rating=1500, count=5):
57
- """
58
- Fetches relevant Lichess puzzles based on error types and user rating.
59
- error_types: list of strings (e.g. ['hangingPiece', 'blunder'])
60
- user_rating: int, target puzzle rating
61
- count: int, number of puzzles to fetch
62
- """
63
  puzzles = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  try:
65
- # Lichess API: https://lichess.org/api/puzzle
66
- # We'll use the public puzzle endpoint and filter locally
67
- url = f"https://lichess.org/api/puzzle"
68
- headers = {'Accept': 'application/x-ndjson'}
69
- response = requests.get(url, headers=headers, timeout=10)
70
- if response.status_code != 200:
71
- logger.error("Failed to fetch puzzles from Lichess")
72
- return puzzles
73
-
74
- lines = response.text.strip().split('\n')
75
- for line in lines:
76
  if len(puzzles) >= count:
77
  break
 
 
 
 
 
 
 
 
 
78
  try:
79
- puzzle = requests.utils.json.loads(line)
80
- # Filter by rating and theme (error type)
81
- if abs(puzzle.get('rating', 1500) - user_rating) <= 150:
82
- if any(theme in puzzle.get('themes', []) for theme in error_types):
83
- puzzles.append({
84
- 'id': puzzle['id'],
85
- 'url': f"https://lichess.org/training/{puzzle['id']}",
86
- 'theme': ', '.join(puzzle.get('themes', [])),
87
- 'rating': puzzle.get('rating', 1500),
88
- 'fen': puzzle.get('fen', '')
89
- })
90
- except Exception as e:
91
- continue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  except Exception as e:
93
  logger.error(f"Error fetching puzzles: {str(e)}")
 
 
 
 
 
 
 
 
 
 
 
94
  return puzzles
 
54
 
55
 
56
  def fetch_lichess_puzzles(error_types, user_rating=1500, count=5):
 
 
 
 
 
 
57
  puzzles = []
58
+
59
+ # Map Uzbek error categories to Lichess puzzle themes
60
+ theme_mapping = {
61
+ "Qo'pol xatolar": ["mate", "mateIn1", "mateIn2", "hangingPiece"],
62
+ "Kichik xatolar": ["advantage", "crushing", "attackingF2F7"],
63
+ "Himoyasiz qoldirish": ["hangingPiece", "pin", "skewer", "discoveredAttack"],
64
+ "Debyut xatolari": ["opening", "middlegame"],
65
+ "O'rta o'yin xatolari": ["middlegame", "fork", "defensiveMove"],
66
+ "Endshpil xatolari": ["endgame", "advancedPawn", "promotion"]
67
+ }
68
+
69
+ # Convert error types to Lichess themes
70
+ lichess_themes = []
71
+ for error_type in error_types:
72
+ if error_type in theme_mapping:
73
+ lichess_themes.extend(theme_mapping[error_type])
74
+
75
+ lichess_themes = list(set(lichess_themes))
76
+
77
+ if not lichess_themes:
78
+ lichess_themes = ["tactics"]
79
+
80
  try:
81
+ for theme in lichess_themes[:3]: # Limit to top 3 themes
 
 
 
 
 
 
 
 
 
 
82
  if len(puzzles) >= count:
83
  break
84
+
85
+ url = f"https://lichess.org/api/puzzle/daily"
86
+ headers = {'Accept': 'application/json'}
87
+
88
+ params = {
89
+ 'max': count,
90
+ 'theme': theme
91
+ }
92
+
93
  try:
94
+ response = requests.get(
95
+ "https://lichess.org/api/puzzle/activity",
96
+ headers=headers,
97
+ timeout=10
98
+ )
99
+
100
+ if response.status_code == 200:
101
+ data = response.json()
102
+
103
+ # Filter by rating range
104
+ for item in data.get('puzzles', []):
105
+ if len(puzzles) >= count:
106
+ break
107
+
108
+ puzzle_rating = item.get('puzzle', {}).get('rating', 1500)
109
+
110
+ if abs(puzzle_rating - user_rating) <= 300:
111
+ puzzle_id = item.get('puzzle', {}).get('id')
112
+ puzzle_themes = item.get('puzzle', {}).get('themes', [])
113
+
114
+ puzzles.append({
115
+ 'id': puzzle_id,
116
+ 'url': f"https://lichess.org/training/{puzzle_id}",
117
+ 'theme': theme.title(),
118
+ 'rating': puzzle_rating,
119
+ 'themes': puzzle_themes
120
+ })
121
+ except:
122
+ pass
123
+
124
+ # If no puzzles found, provide generic training links
125
+ if not puzzles:
126
+ for i, theme in enumerate(lichess_themes[:count]):
127
+ puzzles.append({
128
+ 'id': f'theme_{i}',
129
+ 'url': f"https://lichess.org/training/{theme}",
130
+ 'theme': theme.title(),
131
+ 'rating': user_rating,
132
+ 'themes': [theme]
133
+ })
134
+
135
  except Exception as e:
136
  logger.error(f"Error fetching puzzles: {str(e)}")
137
+
138
+ for i, error_type in enumerate(error_types[:count]):
139
+ theme = theme_mapping.get(error_type, ["tactics"])[0]
140
+ puzzles.append({
141
+ 'id': f'fallback_{i}',
142
+ 'url': f"https://lichess.org/training/{theme}",
143
+ 'theme': error_type,
144
+ 'rating': user_rating,
145
+ 'themes': [theme]
146
+ })
147
+
148
  return puzzles