From 948f8863f352b9de45ba120a12eb1ef6d1aa4e23 Mon Sep 17 00:00:00 2001 From: Dennis Kobert Date: Wed, 1 Jul 2020 19:54:18 +0200 Subject: Add basic plantuml parser --- secateurs.py | 44 ++++++++ test.plm | 356 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 400 insertions(+) create mode 100644 secateurs.py create mode 100644 test.plm diff --git a/secateurs.py b/secateurs.py new file mode 100644 index 0000000..7111c04 --- /dev/null +++ b/secateurs.py @@ -0,0 +1,44 @@ +import plantuml +import sys + +f = open(sys.argv[1], 'r').readlines() +p = plantuml.PlantUML(url="http://www.plantuml.com/plantuml/img/") + +preamble = [] + + +def add_preamble(offset): + for line in range(offset, len(f)): + if "namespace" in f[line]: + return line - 1 + else: + preamble.append(f[line]) + + +def generate_svg(text): + print(f"generating: {text}") + res = p.get_url(plantuml_text=('\n'.join(preamble) + text)) + print(res) + + +def parse_namespace(offset): + print(f"offset: {offset}") + depth = 1 + contains_subspaces = False + for i in range(offset + 2, len(f)): + #print(f[i]) + depth += f[i].count("{") - f[i].count("}") + if "namespace" in f[i]: + print("parsing subnamespace") + contains_subspaces = True + parse_namespace(i) + if depth == 0: + if not contains_subspaces: + generate_svg('\n'.join(f[offset:i + 1])) + return i + + +offset = 0 +while offset < len(f): + offset = add_preamble(offset) + offset = parse_namespace(offset) diff --git a/test.plm b/test.plm new file mode 100644 index 0000000..fc3fad0 --- /dev/null +++ b/test.plm @@ -0,0 +1,356 @@ +skinparam linetype ortho + +namespace django #DDDDDD { + namespace django.db.models { + class FileField {} + class FieldFile {} + class FileDescriptor {} + } + + namespace django.views { + class View <>{ + dispatch(): HttpResponse + } + } + + namespace django.forms { + class Form <> + class ModelForm <> + ModelForm -|> Form + } + + namespace django.core.management.base { + class BaseCommand + } + + namespace django.contrib.auth.base_user { + class AbstractBaseUser << (M,orchid) >> + } + 'django.contrib.auth.base_user.AbstractBaseUser -d-|>django.db.models.Model + +} + +namespace django-media-fields.models { + AudioField -|> django.db.models.FileField + class AudioField { + length_field: str + + update_metadata_fields(self, instance, force=False, *args, **kwargs) + } + AudioFileDescriptor -|> django.db.models.FileDescriptor + AudioFieldFile -|> django.db.models.FieldFile + AudioField -[hidden]d- AudioFileDescriptor + AudioFileDescriptor -[hidden]d- AudioFieldFile + + AudioFieldFile -[hidden]d- VideoField + + VideoField -|> django.db.models.FileField + class VideoField { + length_field: str + width_field: str + height_field: str + + update_metadata_fields(self, instance, force=False, *args, **kwargs) + } + VideoFileDescriptor -|> django.db.models.FileDescriptor + VideoFieldFile -d-|> django.db.models.FieldFile + VideoField -[hidden]d- VideoFileDescriptor + VideoFileDescriptor -[hidden]d- VideoFieldFile +} + + + +namespace dill { + namespace dill.accounts { + namespace dill.accounts.backends { + class BaseBackend { + authenticate(request: Request, **kwargs); + get_user(user_id: int): User + } + + HttpUserBackend -d-|> BaseBackend + class HttpUserBackend { + authenticate(request: Request, **kwargs): User + } + + LDAPBackend -d-|> BaseBackend + class LDAPBackend { + authenticate(request: Request, username: str, password: str, **kwargs): User + } + + ShibbolethBackend -r-|> BaseBackend + class ShibbolethBackend { + authenticate(request: Request, **kwargs): User + } + } + + namespace dill.accounts.mixins { + class AccessMixin { + login_url: str + redirect_field_name: str + permission_denied_message: str + + dispatch(request: Request, *args, **kwargs): Response + check_permission(user: User): bool + handle_no_permission(): Response + handle_unauthenticated(): Response + get_permission_denied_message(): str + } + + LoginRequiredMixin -|> AccessMixin + class LoginRequiredMixin { + check_permission(user: User): bool + } + + PermissionRequiredMixin -|> AccessMixin + class PermissionRequiredMixin { + required_permission: [Perm] + + check_permission(user: User): bool + } + + + + } + + namespace dill.accounts.models { + class PermissionMixin { + get_implicit_groups(): [Group] + get_explicit_groups(): [Group] + get_groups(): [Group] + get_all_permissions(): set + has_perms(perms: [Perm]): bool + } + + User -|> django.contrib.auth.base_user.AbstractBaseUser + User .|> PermissionMixin + class User << (M, orchid) >> { + username: CharField + first_name: CharField + last_name: CharField + mail: EmailField + profile_image: ImageField + + clean() + get_full_name(): str + get_short_name(): str + get_implicit_groups(): [Group] + + << deprecated >> is_anonymous(): bool + is_authenticated(): bool + } + User *- "many" UserGroup: groups + + ' AnonymousUser is not a model do not mark it as such + AnonymousUser -|> User + + 'UserGroup -|> django.db.models.Model + class UserGroup << (M,orchid) >> { + name: CharField + } + } + + namespace dill.accounts.permissions { + class Perm { + app: str + key: str + description: str + + __init__(app: str, key: str, description: str) + } + } + + namespace dill.accounts.management.commands { + namespace dill.accounts.management.commands.createuser { + Command -|> django.core.management.base.BaseCommand + class Command { + add_argument(parser: OptionParser) + handle(*args, **kwargs) + } + } + + namespace dill.accounts.management.commands.promoteuser { + Command -|> django.core.management.base.BaseCommand + class Command { + add_argument(parser: OptionParser) + handle(*args, **kwargs) + } + } + } + + namespace dill.accounts.views { + + class LoginView << (V,lightblue) >> + 'LoginView -|> django.views.View + class LogoutView << (V,lightblue) >> + 'LogoutView -|> django.views.View + class ProfileView << (V,lightblue) >> + 'ProfileView -|> django.views.View + ProfileView .|> dill.accounts.mixins.LoginRequiredMixin + class ProfileEditView << (V,lightblue) >> + + dill.accounts.mixins.PermissionRequiredMixin <|- dill.accounts.views.ProfileEditView + + } + + namespace dill.accounts.forms { + class AuthenticationForm <> + + AuthenticationForm o-- dill.accounts.views.LoginView + + class ProfileForm <> + ProfileForm -|> django.forms.ModelForm + ProfileForm o-- dill.accounts.views.ProfileEditView + } + + namespace dill.accounts.middleware { + class AuthenticationMiddleware { + - cached_user: User + + __init__(get_response: callable) + __call__(request: Request): Request + get_user(request: Request): User + } + } + + namespace dill.accounts.templatetags.perms { + class PermWrapper { + __init__(user: User) + __iter__(): iterator + __contains__(perm: Perm): bool + } + } + } + + namespace dill.models { + 'subpackage? + 'Experiment -|> django.db.models.Model + class Experiment << (M,orchid) >> { + name: CharField + description: TextField + archived_at: DateTimeField + created_at: DateTimeField + __str__() + } + Experiment -> dill.accounts.models.User: creator + Experiment "many" <- dill.accounts.models.User: favorites + 'Tag -|> django.db.models.Model + class Tag << (M,orchid) >> { + name: CharField + color: IntegerField + __str__() + } + Tag --* Experiment + + + class "//NoteMedia//" as NoteMedia << (M,orchid) >> { + name: CharField + content_type: CharField + size: IntegerField + thumb: ImageField + thumb_height: IntegerField + thumb_width: IntegerField + + save() + } + + class Note << (M,orchid) >> { + content: TextField + created_at: DateTimeField + __str__() + } + + AudioMedia -|> NoteMedia + class AudioMedia << (M,orchid) >> { + file: django_file_fields.models.AudioField + length: IntegerField + + __str__() + } + + ImageMedia -|> NoteMedia + class ImageMedia << (M,orchid) >> { + file: ImageField + height: IntegerField + width: IntegerField + + __str__() + } + + VideoMedia -|> NoteMedia + class VideoMedia << (M,orchid) >> { + file: djang_file_fields.models.VideoField + length: IntegerField + height: IntegerField + width: IntegerField + } + + NoteMedia -[hidden]d- Note + NoteMedia -[hidden]d- AudioMedia + AudioMedia -[hidden]d- VideoMedia + VideoMedia -[hidden]d- ImageMedia + Note -d---> dill.accounts.models.User: creator + Note -> "many" Tag: tags + Note *- "many" NoteMedia: media + Note -* Experiment: experiment + } + + namespace dill.views { + 'subpackage? + class ExperimentView << (V,lightblue) >> + 'TODO change to ExperimentDetailView? + dill.accounts.mixins.PermissionRequiredMixin <|- dill.views.ExperimentView + + 'ExperimentView -|> django.views.View + class ExperimentEditView << (V,lightblue) >> + 'ExperimentEditView -|> django.views.View + class Startpage << (V,lightblue) >> + class SearchResultPage << (V, lightblue) >> + + } + + namespace dill.forms { + 'subpackage? + class ExperimentForm <> + ExperimentForm -|> django.forms.ModelForm + ExperimentForm o-- dill.views.ExperimentEditView + + class NoteForm <> + NoteForm o-- dill.views.ExperimentView + } + + namespace dill.admin { + namespace dill.admin.views { + class ExportView << (V,lightblue) >> + class UserListView << (V,lightblue) >> + 'ExportView -|> django.views.View + dill.admin.views.ExportView -|> dill.accounts.mixins.PermissionRequiredMixin + dill.accounts.mixins.PermissionRequiredMixin <|- dill.admin.views.UserListView + + } + } + + 'django-media-fields.models.VideoField -[hidden]d- django.contrib.auth.base_user.AbstractBaseUser + + ' make it nice + django.contrib.auth.base_user.AbstractBaseUser -[hidden]d- django.core.management.base.BaseCommand + 'django.forms -[hidden]u- django.db.models + django.core.management.base.BaseCommand -[hidden]d- django.forms + 'django.views -[hidden]u- django.forms + dill.accounts.middleware -[hidden]d- dill.admin + 'django.forms -[hidden]d- django.core.management.base.BaseCommand + 'django.core.management.base.BaseCommand -[hidden]d- django.views + dill.models --[hidden]d- dill.accounts + + dill.accounts.mixins.LoginRequiredMixin --[hidden]l- dill.accounts.mixins.AccessMixin + + dill.accounts.models -[hidden]d- dill.accounts.management.commands + dill.accounts.management.commands -[hidden]l- dill.accounts.permissions + dill.accounts.permissions --[hidden]d- dill.accounts.backends + dill.accounts.backends --[hidden]d- dill.accounts.forms + dill.accounts.views -[hidden]d- dill.accounts.mixins + + 'dill.accounts.views -[hidden]d- dill.accounts.forms + dill.accounts.mixins --[hidden]d- dill.accounts.middleware + dill.accounts.middleware -[hidden]l- dill.accounts.templatetags.perms +} -- cgit v1.2.3-54-g00ecf