Skip to content

Commit

Permalink
Dev (#345)
Browse files Browse the repository at this point in the history
  • Loading branch information
lobsam authored Sep 20, 2024
2 parents e68f3e0 + ae5848b commit 9041a55
Show file tree
Hide file tree
Showing 62 changed files with 962 additions and 704 deletions.
Empty file added account/__init__.py
Empty file.
3 changes: 3 additions & 0 deletions account/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.contrib import admin

# Register your models here.
7 changes: 7 additions & 0 deletions account/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.apps import AppConfig

class AccountsConfig(AppConfig):
name = 'account' # The name of your app

# def ready(self):
# import account.signal # Import the signals
27 changes: 27 additions & 0 deletions account/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.29 on 2024-09-18 12:44
from __future__ import unicode_literals

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


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='UserType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('user_type', models.CharField(choices=[('Monastic', 'Monastic'), ('Teacher', 'Teacher'), ('Student', 'Student'), ('Educated* /Dr / Prof', 'Educated* /Dr / Prof'), ('regular user', 'regular user')], max_length=20)),
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
Empty file added account/migrations/__init__.py
Empty file.
19 changes: 19 additions & 0 deletions account/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from django.db import models

from django.contrib.auth.models import User


class UserType(models.Model):
USER_TYPE_CHOICES = [
('Monastic', 'Monastic'),
('Teacher', 'Teacher'),
('Student', 'Student'),
('Educated* /Dr / Prof', 'Educated* /Dr / Prof'),
('regular user', 'regular user'),
]

user = models.OneToOneField(User, on_delete=models.CASCADE)
user_type = models.CharField(max_length=20, choices=USER_TYPE_CHOICES)

def __str__(self):
return f"{self.user.username} - {self.user_type}"
17 changes: 17 additions & 0 deletions account/signal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# from django.db.models.signals import post_save
# from django.dispatch import receiver
# from django.contrib.auth.models import User
# from .models import UserType

# # Automatically create a user profile when a new User is created
# @receiver(post_save, sender=User)
# def create_user_profile(sender, instance, created, **kwargs):
# if created:
# print("UserType created for the new user")
# UserType.objects.create(user=instance)

# # Automatically save the user profile when the User is saved
# @receiver(post_save, sender=User)
# def save_user_profile(sender, instance, **kwargs):
# if hasattr(instance, 'usertype'): # Check if user has an associated UserType
# instance.usertype.save()
3 changes: 3 additions & 0 deletions account/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.
3 changes: 3 additions & 0 deletions account/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.shortcuts import render

# Create your views here.
44 changes: 44 additions & 0 deletions reader/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@
from sefaria.helper.topic import update_topic, update_topic_titles
from sefaria.helper.category import update_order_of_category_children, check_term
from redis_clear import clear_redis_cache
from django.middleware.csrf import get_token
from django.utils.text import slugify
import random
import string

if USE_VARNISH:
from sefaria.system.varnish.wrapper import invalidate_ref, invalidate_linked
Expand Down Expand Up @@ -3984,6 +3988,11 @@ def edit_profile(request):
Page for editing a user's profile.
"""
profile = UserProfile(id=request.user.id)
if not profile.slug:
profile.slug = slugify(request.user.username) or generate_random_slug()
while db.profiles.find_one({"slug": profile.slug, "_id": {"$ne": profile.id}}):
profile.slug = generate_random_slug()
profile.save()
sheets = db.sheets.find({"owner": profile.id, "status": "public"}, {"id": 1, "datePublished": 1}).sort(
[["datePublished", -1]])
return render_template(request, 'edit_profile.html', None, {
Expand All @@ -3992,6 +4001,41 @@ def edit_profile(request):
'sheets': sheets,
})

def generate_random_slug(length=8):
"""
Generates a random slug in case the username slug conflicts or is empty.
"""
letters = string.ascii_lowercase + string.digits
return ''.join(random.choice(letters) for i in range(length))


# @login_required
# @ensure_csrf_cookie
# def edit_profile(request):
# """
# Page for editing a user's profile.
# """
# # Fetch the user's profile
# profile = UserProfile(id=request.user.id)

# # Check if slug is empty or None, and generate a default slug if needed
# if not profile.slug:
# # Generate a default slug using the username
# profile.slug = slugify(request.user.username)
# # Save the profile with the new slug
# profile.save()

# # Get public sheets owned by the user
# sheets = db.sheets.find({"owner": profile.id, "status": "public"}, {"id": 1, "datePublished": 1}).sort(
# [["datePublished", -1]])

# # Render the edit profile page
# return render(request, 'edit_profile.html', {
# 'user': request.user,
# 'profile': profile,
# 'sheets': sheets,
# 'csrf_token': get_token(request), # ensure CSRF token is available in the context
# })

@login_required
@ensure_csrf_cookie
Expand Down
24 changes: 23 additions & 1 deletion sefaria/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from emailusernames.utils import get_user, user_exists
from captcha.fields import ReCaptchaField
from captcha.widgets import ReCaptchaV2Checkbox
from account.models import UserType


from sefaria.helper.crm.crm_mediator import CrmMediator
from sefaria.settings import DEBUG
Expand Down Expand Up @@ -49,6 +51,21 @@ class SefariaNewUserForm(EmailUserCreationForm):
# subscribe_educator = forms.BooleanField(label=_("I am an educator"), help_text=_("I am an educator"), initial=False,
# required=False)

CHOICES = [
('', _('Select an option...')),
('Monastic', _('Monastic')),
('Teacher', _('Teacher')),
('Student', _('Student')),
('Educated* /Dr / Prof', _('Educated* /Dr / Prof')),
('regular user', _('regular user')),
]

# Add the select field
user_type = forms.ChoiceField(
choices=CHOICES,
widget=forms.Select(attrs={'placeholder': _("Select an Option")})
)

captcha_lang = "iw" if get_language() == 'he' else "en"
captcha = ReCaptchaField(
widget=ReCaptchaV2Checkbox(
Expand All @@ -67,7 +84,7 @@ class Meta:
def __init__(self, *args, **kwargs):
super(EmailUserCreationForm, self).__init__(*args, **kwargs)
del self.fields['password2']
self.fields.keyOrder = ["email", "first_name", "last_name", "password1", "captcha"]
self.fields.keyOrder = ["email", "first_name", "last_name", "password1", "captcha", ]
self.fields.keyOrder.append("subscribe_educator")

def clean_email(self):
Expand All @@ -94,6 +111,10 @@ def save(self, commit=True):

if commit:
user.save()

# Save user_type in UserType model
user_type = self.cleaned_data['user_type']
UserType.objects.create(user=user, user_type=user_type)

try:
crm_mediator = CrmMediator()
Expand All @@ -102,6 +123,7 @@ def save(self, commit=True):
educator=self.cleaned_data["subscribe_educator"])
except Exception as e:
logger.error(f"failed to add user to CRM: {e}")


return user

Expand Down
2 changes: 1 addition & 1 deletion sefaria/model/user_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ def errors(self):

existing = db.profiles.find_one({"slug": self.slug, "_id": {"$ne": self._id}})
if existing:
return "The Profile URL you have requested is already in use."
return "Profile URL cannot be empty."
# URL Fields: website, facebook, linkedin
url_val = URLValidator()
try:
Expand Down
9 changes: 9 additions & 0 deletions sefaria/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
# system time zone.
TIME_ZONE = 'America/Halifax'

# ElasticSearch server
# URL to connect to ES server.
# Set this to https://sefaria.org/api/search to connect to production search.
# If ElasticSearch server has a password use the following format: http(s)://{username}:{password}@{base_url}
SEARCH_URL = "http://localhost:9200"

# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'es'
Expand Down Expand Up @@ -64,7 +70,9 @@

# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]

# List of finder classes that know how to find static files in
# various locations.
Expand Down Expand Up @@ -156,6 +164,7 @@
'reader',
'sourcesheets',
'sefaria.gauth',
'account',
'captcha',
'django.contrib.admin',
'anymail',
Expand Down
2 changes: 1 addition & 1 deletion static/css/s2.css
Original file line number Diff line number Diff line change
Expand Up @@ -5953,8 +5953,8 @@ body .ui-autocomplete.dictionary-toc-autocomplete .ui-menu-item a.ui-state-focus
.readerControls .readerTextToc .readerTextTocBox a div {
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
max-width: 100%;
padding: 2px 2px;
}

.readerControls .readerTextToc .readerTextVersion {
Expand Down
8 changes: 8 additions & 0 deletions static/css/static.css
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,14 @@
width: 100%;
box-sizing: border-box;
}
.registrationContent select option {
padding: 12px 20px;
height: initial;
margin: 1% 0px;
cursor: pointer;
width: 100%;
box-sizing: border-box;
}
.registrationContent input::placeholder { /* eventual spec? */
font-family: "Heebo", "Roboto", "Helvetica Neue", "Helvetica", sans-serif;
}
Expand Down
2 changes: 1 addition & 1 deletion static/icons/manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "Sefaria Web",
"name": "Pecha Web",
"icons": [
{
"src": "/favicon-pecha.png?v=xQzLlLp7oR",
Expand Down
4 changes: 2 additions & 2 deletions static/js/AboutBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class AboutBox extends Component {
<span dangerouslySetInnerHTML={ {__html: d.summary} } />
</div>
</div>
)
)
}
return <section className="aboutBox">{detailSection}</section>;
}
Expand All @@ -102,7 +102,7 @@ class AboutBox extends Component {
const no_source_versions = multiple_translations || translationVersions?.length === 1 && !sourceVersion;
const sourceVersionSectionTitle = {en: Sefaria._("text.current_version"), he:Sefaria._("text.current_version")};
const translationVersionsSectionTitle = multiple_translations ? {en: Sefaria._("text.current_translation"), he:Sefaria._("text.current_translation")} : {en: Sefaria._("text.current_translation"), he: Sefaria._("text.current_translation")};
const alternateVersionsSectionTitle = no_source_versions ? {en: Sefaria._("source_versions"), he: Sefaria._("source_versions")} : {en: Sefaria._("alt_source_versions"), he: Sefaria._("alt_source_versions")}
const alternateVersionsSectionTitle = no_source_versions ? {en: Sefaria._("text.version.source_versions"), he: Sefaria._("text.version.source_versions")} : {en: Sefaria._("text.version.alt_source_versions"), he: Sefaria._("text.version.alt_source_versions")}

let detailSection = null;
if (d) {
Expand Down
8 changes: 4 additions & 4 deletions static/js/AboutSheet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const AboutSheet = ({ masterPanelSheetId, toggleSignUpModal }) => {
const newSummary = event.target.value
if (event.target.value.length > 280) {
setValidation({
validationMsg: Sefaria._("summary_limit"),
validationMsg: Sefaria._("sheet.message.summary_limit"),
validationFailed: "summary"
});
}
Expand Down Expand Up @@ -241,7 +241,7 @@ const AboutSheet = ({ masterPanelSheetId, toggleSignUpModal }) => {
tags={tags}
suggestions={suggestions}
onDelete={onTagDelete}
placeholderText={Sefaria._("add_topic")}
placeholderText={Sefaria._("sheet.placeholder.add_topic")}
delimiters={["Enter", "Tab", ","]}
onAddition={onTagAddition}
onValidate={onTagValidate}
Expand All @@ -262,7 +262,7 @@ const AboutSheet = ({ masterPanelSheetId, toggleSignUpModal }) => {
<div className={"publishButton"}>
<div className="publishedText">
<InterfaceText>
{Sefaria._("sheet.your_sheet_is")}<span className="publishedTextBold">{ Sefaria._("published")} </span> { Sefaria._("topic.visible_to_other")}
{Sefaria._("sheet.your_sheet_is")}<span className="publishedTextBold">{ Sefaria._("sheet.published")} </span> { Sefaria._("topic.visible_to_other")}
</InterfaceText>
</div>
<button className="button published" onClick={togglePublish}>
Expand Down Expand Up @@ -296,7 +296,7 @@ const AboutSheet = ({ masterPanelSheetId, toggleSignUpModal }) => {
<div>
<span>{Sefaria.util.localeDate(sheet.dateCreated)}</span>
<span>{sheet.views} {Sefaria._("profile.tab.sheet.tag.views")}</span>
<span>{sheetSaves.length} {Sefaria._("Saves")}</span>
<span>{sheetSaves.length} {Sefaria._("common.saves")}</span>
</div>
{/* {sheet.status !== 'public' ? (<div><span className="unlisted"><img src="/static/img/eye-slash.svg"/><span>{Sefaria._("profile.tab.sheet.tag.not_published")}</span></span></div>) : undefined} */}
</div>
Expand Down
8 changes: 4 additions & 4 deletions static/js/AddToSourceSheet.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ class AddToSourceSheetBox extends Component {
disallowedTagsMode: 'discard',
});
let titleRetval = {
"en": `${sheetTitle} ${Sefaria._("section")}${nodeID}`,
"he": `${sheetTitle} ${Sefaria._("section")}${nodeID}`
"en": `${sheetTitle} ${Sefaria._("sheet.source_sheet.make_ref.section")}${nodeID}`,
"he": `${sheetTitle} ${Sefaria._("sheet.source_sheet.make_ref.section")}${nodeID}`
}
if (refTitles){ //show the refs also of a source, just to be nice
titleRetval["en"] += `(${refTitles["en"]})`;
Expand Down Expand Up @@ -231,7 +231,7 @@ class AddToSourceSheetBox extends Component {
<div className="newSheet noselect">
<input className="newSheetInput noselect" placeholder={Sefaria._("Name New Sheet")}/>
<div className="button small noselect" onClick={this.createSheet} >
<span className={`${Sefaria.languageClassFont()}`}>{ Sefaria._("Create")}</span>
<span className={`${Sefaria.languageClassFont()}`}>{ Sefaria._("common.create")}</span>
</div>
</div>
</div>
Expand Down Expand Up @@ -304,7 +304,7 @@ class AddToSourceSheetWindow extends Component {
<div className="sourceSheetBoxTitle">
<img src="/static/icons/circled-x.svg" className="closeButton" aria-hidden="true" alt="Close" onClick={this.close}/>
{Sefaria._uid ? null : <span>
{Sefaria._("sheet.message.login_before_add_source_sheet")} <a href={"/login" + nextParam}> {Sefaria._("log_in")} </a>
{Sefaria._("sheet.message.login_before_add_source_sheet")} <a href={"/login" + nextParam}> {Sefaria._("common.log_in")} </a>
</span>}
<div className="clearFix"></div>
</div>
Expand Down
Loading

0 comments on commit 9041a55

Please sign in to comment.