Files
service-finder/backend/app/services/social_service.py
2026-03-22 11:02:05 +00:00

103 lines
4.8 KiB
Python
Executable File

from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from datetime import datetime, timezone
import logging
from app.models import ServiceProvider, Vote, ModerationStatus, Competition, UserScore
from app.models.identity import User
from app.schemas.social import ServiceProviderCreate
logger = logging.getLogger(__name__)
class SocialService:
"""
SocialService: Kezeli a közösségi interakciókat, szavazatokat és a moderációt.
Az importok a metódusokon belül vannak a körkörös függőség elkerülése érdekében.
"""
async def create_service_provider(self, db: AsyncSession, obj_in: ServiceProviderCreate, user_id: int):
from app.services.gamification_service import gamification_service
new_provider = ServiceProvider(**obj_in.model_dump(), added_by_user_id=user_id)
db.add(new_provider)
await db.flush()
# Alappontszám az új beküldésért
await gamification_service.process_activity(db, user_id, 50, 10, f"New Provider: {new_provider.name}")
await db.commit()
await db.refresh(new_provider)
return new_provider
async def vote_for_provider(self, db: AsyncSession, voter_id: int, provider_id: int, vote_value: int):
from app.services.gamification_service import gamification_service
# Duplikált szavazat ellenőrzése
exists = (await db.execute(select(Vote).where(and_(Vote.user_id == voter_id, Vote.provider_id == provider_id)))).scalar()
if exists:
return {"message": "Már szavaztál erre a szolgáltatóra!"}
db.add(Vote(user_id=voter_id, provider_id=provider_id, vote_value=vote_value))
provider = (await db.execute(select(ServiceProvider).where(ServiceProvider.id == provider_id))).scalar_one_or_none()
if not provider:
return {"error": "Szolgáltató nem található."}
provider.validation_score += vote_value
# Automatikus moderáció figyelése (csak a 'pending' állapotúaknál)
if provider.status == ModerationStatus.pending:
if provider.validation_score >= 5:
provider.status = ModerationStatus.approved
await self._reward_submitter(db, provider.added_by_user_id, provider.name)
elif provider.validation_score <= -3:
provider.status = ModerationStatus.rejected
await self._penalize_user(db, provider.added_by_user_id, provider.name)
await db.commit()
return {"status": "success", "score": provider.validation_score, "new_status": provider.status}
async def get_leaderboard(self, db: AsyncSession, limit: int = 10):
from app.services.gamification_service import gamification_service
if hasattr(gamification_service, 'get_top_users'):
return await gamification_service.get_top_users(db, limit)
return []
async def _reward_submitter(self, db: AsyncSession, user_id: int, provider_name: str):
""" Jutalmazás, ha a beküldött adatot jóváhagyta a közösség. """
from app.services.gamification_service import gamification_service
if not user_id: return
await gamification_service.process_activity(db, user_id, 100, 20, f"Validated: {provider_name}")
# Aktuális verseny keresése és pontozása
now = datetime.now(timezone.utc)
comp_stmt = select(Competition).where(and_(
Competition.is_active == True,
Competition.start_date <= now,
Competition.end_date >= now
))
comp = (await db.execute(comp_stmt)).scalar_one_or_none()
if comp:
us_stmt = select(UserScore).where(and_(UserScore.user_id == user_id, UserScore.competition_id == comp.id))
us = (await db.execute(us_stmt)).scalar_one_or_none()
if not us:
us = UserScore(user_id=user_id, competition_id=comp.id, points=0)
db.add(us)
us.points += 10
async def _penalize_user(self, db: AsyncSession, user_id: int, provider_name: str):
""" Büntetés, ha a beküldött adatot elutasította a közösség (is_penalty=True). """
from app.services.gamification_service import gamification_service
if not user_id: return
# JAVÍTVA: is_penalty=True hozzáadva a gamification híváshoz
await gamification_service.process_activity(db, user_id, 50, 0, f"Rejected: {provider_name}", is_penalty=True)
user = (await db.execute(select(User).where(User.id == user_id))).scalar_one_or_none()
if user and hasattr(user, 'reputation_score'):
user.reputation_score = (user.reputation_score or 0) - 2
if user.reputation_score <= -10:
user.is_active = False
social_service = SocialService()