from flask import Flask, request, jsonify from pymongo import MongoClient, DESCENDING, TEXT from datetime import datetime from config import App, Mongo, Parser from collect import split_by_days app = Flask(__name__) client = MongoClient(f'mongodb://{Mongo.Username}:{Mongo.Password}@{Mongo.Host}:{Mongo.Port}') # MongoDB connection string db = client[Mongo.Database] # Database name if Mongo.Collection not in db.list_collection_names(): db.create_collection(Mongo.Collection) collection = db[Mongo.Collection] # Collection name # Specify the field and options for the index stars_index_key = [('stargazers.totalCount', DESCENDING)] repo_name_index_key = [('nameWithOwner')] if 'stars' not in collection.index_information(): collection.create_index(stars_index_key, name='stars') if 'repoName' not in collection.index_information(): collection.create_index(repo_name_index_key, unique=True, name='repoName') @app.route('/') def hello(): return 'Hello, World!' # Create a new repository @app.route('/repositories', methods=['POST']) def create_repository(): data = request.get_json() result = collection.insert_one(data) return jsonify({'message': 'Repository created', 'id': str(result.inserted_id)}), 201 # Read all repositories with pagination @app.route('/repositories', methods=['GET']) def get_all_repositories(): page = int(request.args.get('page', 1)) # Get the page number (default: 1) page_size = int(request.args.get('page_size', 10)) # Get the page size (default: 10) # Get the start and end values for the stargazers.totalCount range from query parameters start_value = int(request.args.get('start_value', Parser.MinStars)) end_value = int(request.args.get('end_value', Parser.MaxStars)) search_filter = None if start_value and end_value: search_filter = { 'stargazers.totalCount': { '$gte': start_value, '$lte': end_value } } # Calculate the skip value based on the page and page_size skip = (page - 1) * page_size # Retrieve repositories with pagination repositories = list(collection.find(search_filter).skip(skip).limit(page_size)) # Convert ObjectId to string for JSON serialization for each repository for repo in repositories: repo['_id'] = str(repo['_id']) return jsonify(repositories), 200 # Read a specific repository by ID @app.route('/repositories/', methods=['GET']) def get_repository(repository_id): repository = collection.find_one({'_id': repository_id}) if repository: return jsonify(repository), 200 else: return jsonify({'message': 'Repository not found'}), 404 # Update a repository by ID @app.route('/repositories/', methods=['PUT']) def update_repository(repository_id): data = request.get_json() result = collection.update_one({'_id': repository_id}, {'$set': data}) if result.modified_count > 0: return jsonify({'message': 'Repository updated'}), 200 else: return jsonify({'message': 'Repository not found'}), 404 # Delete a repository by ID @app.route('/repositories/', methods=['DELETE']) def delete_repository(repository_id): result = collection.delete_one({'_id': repository_id}) if result.deleted_count > 0: return jsonify({'message': 'Repository deleted'}), 200 else: return jsonify({'message': 'Repository not found'}), 404 # Parse repositories according to min and max stars from env @app.route('/parse', methods=['GET']) def parse(): stars_start = Parser.MinStars stars_finish = Parser.MaxStars if stars_start is None or stars_finish is None: return jsonify({'message': 'Invalid input. Both stars_start and stars_finish should be numbers.'}), 400 stars = f'{stars_start}..{stars_finish}' split_by_days(stars, datetime(2007, 1, 1), datetime(2024, 2, 2)) try: return jsonify({'message': 'Data parsed'}, 200) except Exception as e: return jsonify({'message': 'Data not parsed', 'stack': str(e)}, 500) if __name__ == '__main__': app.run(debug=True, port=App.Port)