Compare commits

...

3 Commits

Author SHA1 Message Date
38a68dbd3d WIP get and show timeline
For now the user is hardcoded in the url, don't want to need an
auth at this stage of the development.
2024-11-14 18:11:12 +01:00
15337cfe58 Changes in PublicationCache model 2024-11-14 18:10:06 +01:00
1dd2aeb7eb Change default database charset 2024-11-14 18:09:35 +01:00
8 changed files with 109 additions and 2 deletions

View File

@ -83,6 +83,9 @@ DATABASES = {
'PASSWORD': config('MYSQL_PASSWORD'), 'PASSWORD': config('MYSQL_PASSWORD'),
'HOST': config('MYSQL_HOST'), 'HOST': config('MYSQL_HOST'),
'PORT': config('MYSQL_PORT'), 'PORT': config('MYSQL_PORT'),
'OPTIONS': {
'charset': 'utf8mb4',
},
} }
} }

View File

@ -15,8 +15,9 @@ Including another URLconf
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
""" """
from django.contrib import admin from django.contrib import admin
from django.urls import path from django.urls import path, include
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('', include('core.urls')),
] ]

View File

@ -0,0 +1,28 @@
# Generated by Django 5.1.3 on 2024-11-14 16:53
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('core', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='publicationcache',
name='author_name',
field=models.CharField(default='', max_length=255, verbose_name='Author Name'),
),
migrations.AddField(
model_name='publicationcache',
name='cid',
field=models.CharField(default='', max_length=255, verbose_name='CID'),
),
migrations.AddField(
model_name='publicationcache',
name='uri',
field=models.CharField(default='', max_length=255, verbose_name='URI'),
),
]

View File

@ -32,7 +32,10 @@ class PublicationCache(models.Model):
related_name="cached_publications") related_name="cached_publications")
content = models.TextField("Content") content = models.TextField("Content")
author = models.CharField("Author", max_length=255) author = models.CharField("Author", max_length=255)
author_name = models.CharField("Author Name", default="", max_length=255)
published_at = models.DateTimeField("Published At") published_at = models.DateTimeField("Published At")
uri = models.CharField("URI", default="", max_length=255)
cid = models.CharField("CID", default="", max_length=255)
is_unread = models.BooleanField("Unread", default=True) is_unread = models.BooleanField("Unread", default=True)
def mark_as_read(self): def mark_as_read(self):

View File

@ -0,0 +1,7 @@
{% for publication in publications %}
<div class="post">
<p><strong>{{ publication.author_name }} ({{ publication.author_handle }})</strong> <span>{{ publication.published_at }}</span></p>
<p>{{ publication.content }}</p>
<a href="{{ publication.uri }}" target="_blank">View post</a>
</div>
{% endfor %}

7
src/core/urls.py Normal file
View File

@ -0,0 +1,7 @@
from django.urls import path
from . import views
urlpatterns = [
path('timeline/<int:user_id>/', views.user_timeline, name='user_timeline'),
]

View File

@ -1,3 +1,60 @@
import requests
from django.shortcuts import render from django.shortcuts import render
from django.http import JsonResponse
from .models import PublicationCache, User
from django.conf import settings
from django.db import IntegrityError
# Create your views here. def user_timeline(request, user_id):
try:
user = User.objects.get(id=user_id)
headers = {'Authorization': f"Bearer {user.access_token}"}
timeline_url = f"{user.pds_url}/xrpc/app.bsky.feed.getTimeline"
# Realizamos la solicitud al PDS
response = requests.get(timeline_url, headers=headers)
if response.status_code != 200:
return JsonResponse({"error": "Failed to retrieve timeline"}, status=500)
feed_data = response.json()
posts = feed_data.get('feed', [])
for post_data in posts:
post = post_data.get('post', {})
record = post.get('record', {})
author = post.get('author', {})
text = record.get('text', '')
created_at = record.get('createdAt', '')
post_id = post.get('uri', '')
if post_id:
publication, created = PublicationCache.objects.get_or_create(
id=post_id,
user=user,
defaults={
'content': text,
'author': author.get('handle', ''),
'author_name': author.get('displayName', ''),
'published_at': created_at,
'uri': post.get('uri', ''),
'cid': post.get('cid', ''),
}
)
if not created:
publication.content = text
publication.author = author.get('handle', '')
publication.author_name = author.get('displayName', '')
publication.published_at = created_at
publication.uri = post.get('uri', '')
publication.cid = post.get('cid', '')
publication.save()
publications = PublicationCache.objects.filter(user=user).order_by('-published_at')
return render(request, 'core/user_timeline.html', {'publications': publications})
except User.DoesNotExist:
return JsonResponse({"error": "User not found"}, status=404)
except IntegrityError as e:
return JsonResponse({"error": str(e)}, status=500)

View File

@ -1,3 +1,4 @@
Django==5.1.3 Django==5.1.3
python-decouple==3.8 python-decouple==3.8
mysqlclient==2.2.6 mysqlclient==2.2.6
requests==2.32.3