Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
narenaryan committed Apr 2, 2023
0 parents commit 39e2080
Show file tree
Hide file tree
Showing 22 changed files with 499 additions and 0 deletions.
13 changes: 13 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
“Commons Clause” License Condition v1.0

The Software is provided to you by the Licensor under the License, as defined below, subject to the following condition.

Without limiting other conditions in the License, the grant of rights under the License will not include, and the License does not grant to you, the right to Sell the Software.

For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you under the License to provide to third parties, for a fee or other consideration (including without limitation fees for hosting or consulting/ support services related to the Software), a product or service whose value derives, entirely or substantially, from the functionality of the Software. Any license notice or attribution required by the License must also include this Commons Clause License Condition notice.

Software: Vidura ChatGPT Prompt System

License: GNU GPL 3.0

Licensor: HappyPythonist.com
22 changes: 22 additions & 0 deletions manage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys


def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'vidura.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)


if __name__ == '__main__':
main()
Empty file added promptbook/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions promptbook/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin
from .models import Category, Prompt, Label, PromptLabel

# Register your models here.

admin.site.register([Category, Prompt, Label, PromptLabel])
6 changes: 6 additions & 0 deletions promptbook/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class PromptbookConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'promptbook'
44 changes: 44 additions & 0 deletions promptbook/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 4.1.7 on 2023-04-02 03:53

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
]

operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('modified_at', models.DateTimeField(auto_now=True)),
],
),
migrations.CreateModel(
name='Prompt',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('text', models.TextField()),
('created_at', models.DateTimeField(auto_now_add=True)),
('modified_at', models.DateTimeField(auto_now=True)),
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='promptbook.category')),
],
),
migrations.CreateModel(
name='Label',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255)),
('created_at', models.DateTimeField(auto_now_add=True)),
('modified_at', models.DateTimeField(auto_now=True)),
('category', models.ManyToManyField(to='promptbook.category')),
],
),
]
18 changes: 18 additions & 0 deletions promptbook/migrations/0002_alter_label_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 4.1.7 on 2023-04-02 05:18

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('promptbook', '0001_initial'),
]

operations = [
migrations.AlterField(
model_name='label',
name='category',
field=models.ManyToManyField(to='promptbook.prompt'),
),
]
26 changes: 26 additions & 0 deletions promptbook/migrations/0003_remove_label_category_promptlabel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Generated by Django 4.1.7 on 2023-04-02 05:27

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('promptbook', '0002_alter_label_category'),
]

operations = [
migrations.RemoveField(
model_name='label',
name='category',
),
migrations.CreateModel(
name='PromptLabel',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('label', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='promptbook.label')),
('prompt', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='promptbook.prompt')),
],
),
]
Empty file.
33 changes: 33 additions & 0 deletions promptbook/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from django.db import models

class Category(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)

def __str__(self):
return self.name

class Prompt(models.Model):
text = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)

def __str__(self):
return self.text[:50] + '...' if len(self.text) > 50 else self.text

class Label(models.Model):
name = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)

def __str__(self):
return self.name

class PromptLabel(models.Model):
label = models.ForeignKey(Label, on_delete=models.DO_NOTHING)
prompt = models.ForeignKey(Prompt, on_delete=models.DO_NOTHING)

def __str__(self):
return f"Label: {self.label.__str__()}, Prompt: {self.prompt.__str__()}"
41 changes: 41 additions & 0 deletions promptbook/templates/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vidura</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
</head>
<body>
<nav class="navbar" role="navigation" aria-label="main navigation">
<div class="container">
<div class="navbar-brand">
<a class="navbar-item" href="{% url 'list_categories' %}">
<strong>Vidura (ChatGPT Prompt System)</strong>
</a>
</div>
<div class="navbar-menu">
<div class="navbar-start">
<a class="navbar-item" href="{% url 'list_categories' %}">
Categories
</a>
</div>
<div class="navbar-end">
{% if user.is_authenticated %}
<a class="navbar-item" href="{% url 'logout' %}">
Logout
</a>
{% endif %}
</div>
</div>
</div>
</nav>
<section class="section">
<div class="container">
{% block content %}
{% endblock %}
</div>
</section>
</body>
</html>
16 changes: 16 additions & 0 deletions promptbook/templates/list_categories.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends 'base.html' %}

{% block content %}
<h1 class="title">Categories</h1>
<div class="columns is-multiline">
{% for category in categories %}
<div class="column is-one-third">
<div class="card">
<div class="card-content">
<h3 class="subtitle"><a href="{% url 'list_prompts' category.id %}">{{ category.name }}</a></h3>
</div>
</div>
</div>
{% endfor %}
</div>
{% endblock %}
32 changes: 32 additions & 0 deletions promptbook/templates/list_prompts.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{% extends 'base.html' %}

{% block content %}
<h1 class="title">Prompts in category: {{ category.name }}</h1>
<div class="columns is-multiline">
{% for prompt in prompts %}
<div class="column is-one-third">
<div class="box">
<div class="content">
<p>{{ prompt.text|truncatechars:250 }} <span class="tag is-light">Length: {{ prompt.text|length }} chars...</span></p>
<div class="tags">
{{ prompt_labels }}
{% for label in prompt_labels.prompt.id %}
<span class="tag is-rounded">{{ label }}</span>
{% endfor %}
</div>
</div>
<button class="button is-small" data-clipboard-text="{{ prompt.text }}">
<span class="icon">
<i class="fas fa-copy"></i>
</span>
</button>
</div>
</div>
{% endfor %}
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.8/clipboard.min.js"></script>
<script>
new ClipboardJS('.button');
</script>
{% endblock %}
Empty file added promptbook/templates/login.html
Empty file.
3 changes: 3 additions & 0 deletions promptbook/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
10 changes: 10 additions & 0 deletions promptbook/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path

from . import views

urlpatterns = [
path('login/', views.login, name='login'),
path('categories/', views.list_categories, name='list_categories'),
path('categories/<int:category_id>/prompts/', views.list_prompts, name='list_prompts'),
path('logout/', views.logout, name='logout'),
]
45 changes: 45 additions & 0 deletions promptbook/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from django.shortcuts import render
from .models import Category, Prompt, PromptLabel
from django.contrib.auth import login as auth_login
from django.contrib.auth import logout as auth_logout
from django.contrib.auth.forms import AuthenticationForm
from django.shortcuts import render, redirect

def list_categories(request):
categories = Category.objects.all()
context = {'categories': categories}
return render(request, 'list_categories.html', context)

def list_prompts(request, category_id):
category = Category.objects.get(pk=category_id)
prompts = category.prompt_set.all()

prompt_labels = {}
for prompt in prompts:
labels = [pl.label for pl in PromptLabel.objects.filter(prompt=prompt)]
prompt_labels[prompt.id] = labels

return render(request, 'list_prompts.html', {
'category': category,
'prompts': prompts,
'prompt_labels': prompt_labels,
})

def login(request):
if request.user.is_authenticated:
return redirect('list_categories')

if request.method == 'POST':
form = AuthenticationForm(request, data=request.POST)
if form.is_valid():
auth_login(request, form.get_user())
return redirect('list_categories')
else:
form = AuthenticationForm(request)
return render(request, 'login.html', {'form': form})



def logout(request):
auth_logout(request)
return redirect('login')
Empty file added vidura/__init__.py
Empty file.
16 changes: 16 additions & 0 deletions vidura/asgi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
"""
ASGI config for vidura project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/howto/deployment/asgi/
"""

import os

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'vidura.settings')

application = get_asgi_application()
Loading

0 comments on commit 39e2080

Please sign in to comment.