Skip to content
Closed
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
211 changes: 211 additions & 0 deletions data/skills_counters.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
{
"python": 0,
"javascript": 0,
"java": 0,
"c++": 0,
"c#": 0,
"ruby": 0,
"php": 0,
"go": 0,
"swift": 0,
"typescript": 0,
"html": 0,
"css": 0,
"sql": 0,
"kotlin": 0,
"rust": 0,
"scala": 0,
"r": 0,
"matlab": 0,
"perl": 0,
"lua": 0,
"haskell": 0,
"elixir": 0,
"erlang": 0,
"clojure": 0,
"f#": 0,
"dart": 0,
"julia": 0,
"groovy": 0,
"assembly": 0,
"bash": 0,
"powershell": 0,
"solidity": 0,
"objective-c": 0,
"cobol": 0,
"fortran": 0,
"zig": 0,
"nim": 0,
"ocaml": 0,
"crystal": 0,
"react": 0,
"angular": 0,
"vue.js": 0,
"fastapi": 0,
"express.js": 0,
"next.js": 0,
"nuxt.js": 0,
"svelte": 0,
"sveltekit": 0,
"remix": 0,
"astro": 0,
"laravel": 0,
"symfony": 0,
"rails": 0,
"asp.net": 0,
"blazor": 0,
"phoenix": 0,
"gin": 0,
"fiber": 0,
"fastify": 0,
"hapi.js": 0,
"koa.js": 0,
"nest.js": 0,
"strapi": 0,
"gatsby": 0,
"htmx": 0,
"alpinejs": 0,
"solid.js": 0,
"qwik": 0,
"jquery": 0,
"bootstrap": 0,
"tailwindcss": 0,
"chakra-ui": 0,
"material-ui": 0,
"shadcn": 0,
"three.js": 0,
"d3.js": 0,
"rxjs": 0,
"node.js": 0,
"django": 0,
"flask": 0,
"spring": 0,
"flutter": 0,
"react-native": 0,
"ionic": 0,
"xamarin": 0,
"maui": 0,
"jetpack-compose": 0,
"swiftui": 0,
"capacitor": 0,
"mongodb": 0,
"postgresql": 0,
"mysql": 0,
"sqlite": 0,
"redis": 0,
"cassandra": 0,
"firebase": 0,
"supabase": 0,
"dynamodb": 0,
"neo4j": 0,
"elasticsearch": 0,
"couchdb": 0,
"influxdb": 0,
"mariadb": 0,
"cockroachdb": 0,
"planetscale": 0,
"prisma": 0,
"sqlalchemy": 0,
"typeorm": 0,
"aws": 0,
"azure": 0,
"gcp": 0,
"docker": 0,
"kubernetes": 0,
"terraform": 0,
"ansible": 0,
"pulumi": 0,
"helm": 0,
"nginx": 0,
"apache": 0,
"linux": 0,
"vercel": 0,
"netlify": 0,
"cloudflare": 0,
"serverless": 0,
"openshift": 0,
"vagrant": 0,
"prometheus": 0,
"grafana": 0,
"datadog": 0,
"git": 0,
"tensorflow": 0,
"pytorch": 0,
"scikit-learn": 0,
"keras": 0,
"huggingface": 0,
"langchain": 0,
"openai-api": 0,
"llm": 0,
"rag": 0,
"computer-vision": 0,
"nlp": 0,
"pandas": 0,
"numpy": 0,
"matplotlib": 0,
"seaborn": 0,
"plotly": 0,
"opencv": 0,
"spark": 0,
"hadoop": 0,
"airflow": 0,
"dbt": 0,
"mlflow": 0,
"wandb": 0,
"jupyter": 0,
"data science": 0,
"machine learning": 0,
"artificial intelligence": 0,
"deep-learning": 0,
"reinforcement-learning": 0,
"generative-ai": 0,
"jest": 0,
"pytest": 0,
"cypress": 0,
"playwright": 0,
"selenium": 0,
"vitest": 0,
"mocha": 0,
"junit": 0,
"testng": 0,
"webpack": 0,
"vite": 0,
"babel": 0,
"eslint": 0,
"prettier": 0,
"github-actions": 0,
"jenkins": 0,
"sonarqube": 0,
"jira": 0,
"figma": 0,
"storybook": 0,
"microservices": 0,
"websockets": 0,
"grpc": 0,
"kafka": 0,
"rabbitmq": 0,
"oauth": 0,
"jwt": 0,
"webassembly": 0,
"pwa": 0,
"electron": 0,
"tauri": 0,
"opengl": 0,
"webgl": 0,
"unity": 0,
"unreal-engine": 0,
"embedded-systems": 0,
"iot": 0,
"arduino": 0,
"raspberry-pi": 0,
"quantum-computing": 0,
"ar/vr": 0,
"cybersecurity": 0,
"blockchain": 0,
"devops": 0,
"ci/cd": 0,
"restapi": 0,
"graphql": 0,
"ui/ux design": 0,
"game development": 0
}
37 changes: 36 additions & 1 deletion routes/main_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from flask import Blueprint, render_template, request, jsonify, send_from_directory, abort

from utils.recommender import get_recommendations, validate_recommendation_inputs
from utils.data_loader import find_project_by_id, get_project_stats
from utils.data_loader import find_project_by_id, get_project_stats, increment_skill_counter, get_top_skills
from utils.file_server import read_starter_code, resolve_starter_file, get_starter_code_dir

# Create the Blueprint that app.py will register
Expand Down Expand Up @@ -61,6 +61,41 @@ def recommend():
return jsonify({"projects": results}), 200


@main.route("/api/top-skills", methods=["GET"])
def top_skills():
"""
Return the top 5 most-selected skills across the community.
Returns a JSON array of skill objects with 'label' and 'counter' properties.
"""
top_5 = get_top_skills(5)
return jsonify({"skills": top_5}), 200


@main.route("/api/track-skill", methods=["POST"])
def track_skill():
"""
Increment the counter for a given skill.
Expects JSON body with 'skill' field (the skill label).
Returns the updated counter value or an error message.
"""
payload = request.get_json()

if not payload:
return jsonify({"error": "Request body must be valid JSON."}), 400

skill = payload.get("skill", "").strip()

if not skill:
return jsonify({"error": "Skill name is required."}), 400

counter_value = increment_skill_counter(skill)

if counter_value == -1:
return jsonify({"error": f"Skill '{skill}' not found."}), 404

return jsonify({"skill": skill, "counter": counter_value}), 200


@main.route("/project/<int:project_id>")
def project_detail(project_id):
"""Render the full detail page for a single project."""
Expand Down
Loading
Loading