Skip to content

Commit

Permalink
Feature/user bitmap (#65)
Browse files Browse the repository at this point in the history
* upgrade python version and django 5.0.7

* add docker and related documentation

* Update docker-compose.yml

* Update admin.py

* Create 0037_datasetbitmapposition_userbitmap.py

* Update __init__.py

* Create datasetBitmapPosition.py

* Create userBitmap.py

* Update docker-compose.yml

* Update admin.py

* Create checksystemhealth.py

* Create checkuserbitmap.py

* commit migrations

* Update datasetBitmapPosition.py

* Update checkuserbitmap.py

* Update userBitmap.py

* Update settings.py

* Update admin.py

* Update userBitmap.py

* Update checksystemhealth.py
  • Loading branch information
danieleguido authored Aug 14, 2024
1 parent 8d42fd7 commit 5e92f25
Show file tree
Hide file tree
Showing 17 changed files with 561 additions and 54 deletions.
Empty file added .docker/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,8 @@ ___*
*.rdb
*.json
.DS_Store


# local docker settings and config
.docker/*
!.docker/.gitkeep
4 changes: 2 additions & 2 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pip = "*"
celery = "*"
requests = "*"
redis = "*"
django = "==5.0.4"
django = "==5.0.7"
pymysql = "*"
django-registration = "*"
gunicorn = "*"
Expand All @@ -18,4 +18,4 @@ gunicorn = "*"
"flake8" = "*"

[requires]
python_version = "3.12.2"
python_version = "3.12.4"
86 changes: 43 additions & 43 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 47 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,58 @@
# impresso-user-admin

A basic django application to manage user-related information contained in [Impresso's Master DB](https://github.com/impresso/impresso-master-db).
We use `pipenv`for development and `docker` for production. Please look at the relevant sections in the documentation.
We use `pipenv` for development together with `docker`. Please look at the relevant sections in the documentation.

To start _django admin_ in development with pipenv:
## Development

ENV=dev pipenv run ./manage.py runserver
Take the time to explore the `.example.env` file and the related `./impresso/settings.py` to understand the settings that can be configured via environment variables for your specific environment. We have configured `dotenv` in `./impresso/base.py` to allow the loading of different `.env` files. For example, you can use `.env` or `.dev.env` for development, and `.prod.env` to test production settings.

or to test tags:
```sh
# our .dev.env file, that connects to the local redis instance
REDIS_HOST=localhost:6379
IMPRESSO_DB_HOST=localhost
IMPRESSO_DB_PORT=3306
# Then don't forget to fill all SOLR related settings accordiung to your impresso configuration
IMPRESSO_SOLR_URL=http://localhost:8983/solr/impresso
IMPRESSO_SOLR_USER=your-user-reader-only
IMPRESSO_SOLR_PASSWORD=our-user-reader-only-password
IMPRESSO_SOLR_USER_WRITE=your-user-write-allowed
IMPRESSO_SOLR_PASSWORD_WRITE=your-user-write-allowed-password
IMPRESSO_SOLR_PASSAGES_URL=http://localhost:8983/solr/impresso-tr-passages
```

To start the Django admin, you need to have Redis and MySQL running. You can start them by running the command `docker compose up`. Please note that in our YAML file, the ports for Redis and MySQL are exposed to facilitate local development and testing.

```sh
docker compose up -d --env-file=.dev.env
```

Then you can start the development server, e.g. with pipenv and the `dev.env` file:

```sh
ENV=dev pipenv run ./manage.py runserver
```

or with Makefile:

```sh
ENV=dev make run-dev
```

ENV=dev make run-dev
To start _celery_ task manager in development with pipenv, in a new terminal:

To start _celery_ task manager in development with pipenv:
```sh
ENV=dev pipenv run celery -A impresso worker -l info
```

Of course, you can also use a generic `.env file` on development, in this case you don't need to specify the `ENV` variable:

ENV=dev pipenv run celery -A impresso worker -l info
```sh
docker compose up -d
pipenv run ./manage.py runserver
# and in another terminal, to start the celery worker
pipenv run celery -A impresso worker -l info
```

### setup with pyenv + pipenv

Expand All @@ -30,7 +69,7 @@ The last command gives you the version of the local python. If it doesn't meet t
use pyenv install command:

```
pyenv install 3.6.9
pyenv install 3.12.4
```

Use pip to install Pipenv:
Expand Down
29 changes: 29 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
services:
redis:
image: redis:alpine
restart: always
volumes:
- ./.docker/redis:/data
entrypoint: redis-server --appendonly yes
ports:
- 6379:6379
# mysql:
# image: mariadb:lts
# restart: always
# volumes:
# - ./.docker/mysql:/var/lib/mysql
# ports:
# - ${DB_PORT:-3308}:3306
# environment:
# MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:-root}
# MARIADB_DATABASE: ${IMPRESSO_DB_NAME}
# MARIADB_USER: ${IMPRESSO_DB_USER}
# MARIADB_PASSWORD: ${IMPRESSO_DB_PASSWORD}
mysql-tunnel:
image: kroniak/ssh-client
restart: always
volumes:
- ./.docker/config/ssh:/root/.ssh
ports:
- ${IMPRESSO_DB_PORT:-3306}:3306
command: ssh -N impresso-mysql-tunnel
45 changes: 45 additions & 0 deletions impresso/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django import forms
from django.contrib import admin
from django.contrib import messages
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
Expand All @@ -8,10 +9,54 @@
from .models import SearchQuery, ContentItem
from .models import Collection, CollectableItem, Tag, TaggableItem
from .models import Attachment, UploadedImage
from .models import UserBitmap, DatasetBitmapPosition

from impresso.tasks import after_user_activation


@admin.register(UserBitmap)
class UserBitmapAdmin(admin.ModelAdmin):
list_display = ("user", "bitmap_display", "user_plan_display", "num_subscriptions")
search_fields = ["user__username", "user__email"]

def num_subscriptions(self, obj):
return obj.subscriptions.count()

def bitmap_display(self, obj):
if obj.bitmap is None:
return ""
return bin(int.from_bytes(obj.bitmap, byteorder="big"))

def user_plan_display(self, obj):
if obj.bitmap is None:
return "-"
bitmap_int = int.from_bytes(obj.bitmap, byteorder="big")
bitmap_length = bitmap_int.bit_length()
# Extract the first 5 bits
bitmap_plan = (
bitmap_int >> (bitmap_length - UserBitmap.BITMAP_PLAN_MAX_LENGTH)
) & 0b11111
if bitmap_plan == UserBitmap.USER_PLAN_GUEST:
return "Guest"
if bitmap_plan == UserBitmap.USER_PLAN_AUTH_USER:
return "Impresso Registered User"
if bitmap_plan == UserBitmap.USER_PLAN_EDUCATIONAL:
return "Student or Teacher - Educational User"
if bitmap_plan == UserBitmap.USER_PLAN_RESEARCHER:
return "Researcher - Academic User"

return bin(bitmap_plan)

user_plan_display.short_description = "User Plan"


@admin.register(DatasetBitmapPosition)
class DatasetBitmapPositionAdmin(admin.ModelAdmin):
list_display = ("name", "bitmap_position")
search_fields = ["name"]
readonly_fields = ("bitmap_position",)


@admin.register(Issue)
class IssueAdmin(admin.ModelAdmin):
list_display = (
Expand Down
Loading

0 comments on commit 5e92f25

Please sign in to comment.