diff --git a/src/models.py b/src/models.py index 0a70a81..f0297b6 100644 --- a/src/models.py +++ b/src/models.py @@ -1,5 +1,5 @@ from pydantic import BaseModel -from typing import Optional, List +from typing import Optional, List, Dict, Any from motor.motor_asyncio import AsyncIOMotorClient from datetime import datetime, timedelta import os @@ -7,6 +7,7 @@ import logging import asyncio from dotenv import load_dotenv +from datetime import datetime, timedelta load_dotenv() logger = logging.getLogger(__name__) @@ -41,13 +42,13 @@ class GithubUser(BaseModel): location: Optional[str] = None company: Optional[str] = None twitter_username: Optional[str] = None - followers: int - following: int - public_repos: int - public_gists: int - access_token: str - created_at: str - updated_at: str + followers: Optional[int] = None + following: Optional[int] = None + public_repos: Optional[int] = None + public_gists: Optional[int] = None + access_token: Optional[int] = None + created_at: str = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + updated_at: str = datetime.now().strftime("%Y-%m-%d %H:%M:%S") async def save(self): try: @@ -68,7 +69,15 @@ async def save(self): except Exception as e: logger.error(f"Failed to save user to DB: {str(e)}") raise ValueError("Failed to save user to DB") - + +async def append_user_to_db(username): + try: + user = GithubUser(username=username, name=username, email=username+"@gitmtach.in") + await user.save() + + except Exception as e: + logger.error(f"Failed to save user to DB: {str(e)}") + raise ValueError("Failed to save user to DB") class RepositoryRecommendation(BaseModel): full_name: str @@ -121,6 +130,20 @@ def append_recommendations_to_db(username, recommendations, recommendation_name) raise ValueError("Failed to save user recommendations to DB") +async def get_user_previous_recommendations(username: str) -> list: + try: + # Example query; adjust as per your database schema + user_recommendations = await db.user_recommendations.find_one({"username": username}) + if not user_recommendations: + return [] + + # Assuming the recommendations are stored in 'recommendation_refs' + return user_recommendations.get("recommendation_refs", []) + except Exception as e: + logger.error(f"Database query error: {str(e)}") + raise + + async def get_user_recommendation_by_id(recommendation_id): try: recommendations_collection = db['recommendations'] @@ -138,19 +161,49 @@ async def get_user_recommendation_by_id(recommendation_id): logger.error(f"Failed to get recommendation from DB: {str(e)}") raise ValueError("Failed to get recommendation from DB") +def process_recommendations(urls: List[Dict[str, Any]], + languages_topics) -> List[Dict[str, Any]]: + """ + Process the list of URLs to ensure uniqueness and format them correctly. + + Args: + urls: List of URL recommendations. + + Returns: + Processed list of unique recommendations. + """ + seen_full_names = set() + unique_recommendations = [] + + for rec in urls: + full_name = rec.get("full_name") + if full_name and full_name not in seen_full_names: + seen_full_names.add(full_name) + unique_recommendations.append(rec) + + def match_score(rec): + # Calculate the score based on language and topic match + score = 0 + rec_language = rec.get('language', '') + rec_topics = rec.get('topics', []) + + # Extract user languages and topics + user_languages = languages_topics.get("languages", []) + user_topics = languages_topics.get("topics", []) -async def get_user_previous_recommendations(username: str) -> list: - try: - # Example query; adjust as per your database schema - user_recommendations = await db.user_recommendations.find_one({"username": username}) - if not user_recommendations: - return [] + # Add 2 to the score for a language match + if rec_language in user_languages: + score += 2 - # Assuming the recommendations are stored in 'recommendation_refs' - return user_recommendations.get("recommendation_refs", []) - except Exception as e: - logger.error(f"Database query error: {str(e)}") - raise + # Add 1 to the score for each matching topic + score += sum(1 for topic in rec_topics if topic in user_topics) + + return score + + # Sort the recommendations based on match score in descending order + unique_recommendations.sort(key=match_score, reverse=True) + + return unique_recommendations # TODO: v2 @@ -209,4 +262,71 @@ async def main(): print(recommendations) if __name__ == "__main__": - asyncio.run(main()) \ No newline at end of file + # asyncio.run(main()) + # Example list of URL recommendations + urls = [ + { + "full_name": "pandas-dev/pandas", + "language": "Python", + "topics": ["data-analysis", "data-science"] + }, + { + "full_name": "tensorflow/tensorflow", + "language": "C++", + "topics": ["machine-learning", "deep-learning"] + }, + { + "full_name": "vuejs/vue", + "language": "JavaScript", + "topics": ["vue", "front-end", "javascript", "framework"] + }, + { + "full_name": "d3/d3", + "language": "JavaScript", + "topics": ["visualization", "d3", "data-visualization"] + }, + { + "full_name": "django/django", + "language": "Python", + "topics": ["web", "framework", "django"] + }, + { + "full_name": "numpy/numpy", + "language": "Python", + "topics": ["math", "array", "numpy"] + }, + { + "full_name": "scikit-learn/scikit-learn", + "language": "Python", + "topics": ["machine-learning", "data-science", "scikit-learn"] + }, + { + "full_name": "nodejs/node", + "language": "JavaScript", + "topics": ["nodejs", "javascript", "server"] + }, + { + "full_name": "rails/rails", + "language": "Ruby", + "topics": ["rails", "web", "ruby"] + }, + { + "full_name": "spring-projects/spring-framework", + "language": "Java", + "topics": ["spring", "framework", "java"] + } + ] + + # User's preferred languages and topics + languages_topics = { + "languages": ["Python", "JavaScript"], + "topics": ["machine-learning", "data-science", "web", "visualization"] + } + + # Process and sort the recommendations + sorted_recommendations = process_recommendations(urls, languages_topics) + + # Display the sorted recommendations + for rec in sorted_recommendations: + print(f"Repo: {rec['full_name']}, Language: {rec['language']}, Topics: {rec['topics']}") + \ No newline at end of file