118 lines
4.1 KiB
Python

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/<repository_id>', 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/<repository_id>', 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/<repository_id>', 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)