from django.tasks import task from social.connectors.linkedin import LinkedInConnector from social.connectors.meta import MetaConnector from social.models import Platform, SocialPost, SocialPostTarget def _connector_for(platform: str): if platform in {Platform.FACEBOOK, Platform.INSTAGRAM}: return MetaConnector() if platform == Platform.LINKEDIN: return LinkedInConnector() raise ValueError(f"Unknown platform: {platform}") @task def publish_social_post(post_id: str) -> None: try: post = SocialPost.objects.prefetch_related("targets__account").get(pk=post_id) except SocialPost.DoesNotExist: return post.status = SocialPost.Status.PUBLISHING post.save(update_fields=["status", "updated_at"]) any_ok = False for target in post.targets.all(): try: remote_id = _connector_for(target.platform).publish(post, target) target.status = SocialPostTarget.Status.PUBLISHED target.remote_id = remote_id target.error = "" target.save(update_fields=["status", "remote_id", "error", "updated_at"]) any_ok = True except Exception as exc: # noqa: BLE001 target.status = SocialPostTarget.Status.FAILED target.error = str(exc)[:2000] target.save(update_fields=["status", "error", "updated_at"]) post.status = ( SocialPost.Status.PUBLISHED if any_ok else SocialPost.Status.FAILED ) if not any_ok: post.error = "All targets failed" post.save(update_fields=["status", "error", "updated_at"]) @task def publish_social_target(target_id: str) -> None: try: target = SocialPostTarget.objects.select_related("post", "account").get( pk=target_id ) except SocialPostTarget.DoesNotExist: return remote_id = _connector_for(target.platform).publish(target.post, target) target.status = SocialPostTarget.Status.PUBLISHED target.remote_id = remote_id target.save(update_fields=["status", "remote_id", "updated_at"])