Changeset 2064
- Timestamp:
- 06/25/09 11:21:23 (9 months ago)
- Files:
-
- 1 modified
Legend:
- Unmodified
- Added
- Removed
-
branches/0.9/pylucid_project/apps/pylucid/models.py
r2060 r2064 43 43 from pylucid_project.utils import crypt 44 44 45 from pylucid.system.auto_model_info import UpdateInfoBaseModel, AutoSiteM2M45 from pylucid.system.auto_model_info import UpdateInfoBaseModel, AutoSiteM2M 46 46 from pylucid.shortcuts import user_message_or_warn 47 47 from pylucid.fields import ColorValueField … … 52 52 """ 53 53 Manager class for PageTree model 54 54 55 55 inherited from models.Manager: 56 56 get_or_create() method, witch expected a request object as the first argument. … … 67 67 raise 68 68 return root_page 69 69 70 70 def get_model_instance(self, request, ModelClass, pagetree=None): 71 71 """ … … 79 79 # default Language instance set in system preferences: 80 80 default_lang_entry = request.PYLUCID.default_lang_entry 81 81 82 82 lang_entry = request.PYLUCID.lang_entry 83 83 default_lang_entry = request.PYLUCID.default_lang_entry 84 84 85 85 if not pagetree: 86 86 # current pagetree instance 87 87 pagetree = request.PYLUCID.pagetree 88 88 89 89 queryset = ModelClass.objects.all().filter(page=pagetree) 90 90 try: … … 94 94 # Get the PageContent entry in the system default language 95 95 return queryset.get(lang=default_lang_entry) 96 96 97 97 def get_pagemeta(self, request, pagetree=None): 98 98 """ … … 102 102 """ 103 103 return self.get_model_instance(request, PageMeta, pagetree) 104 104 105 105 def get_pagecontent(self, request, pagetree=None): 106 106 """ … … 110 110 """ 111 111 return self.get_model_instance(request, PageContent, pagetree) 112 112 113 113 def get_page_from_url(self, url_path): 114 114 """ returns a tuple the page tree instance from the given url_path""" … … 124 124 if page.type == PageTree.PLUGIN_TYPE: 125 125 # It's a plugin 126 prefix_url = "/".join(path[:no +1])127 rest_url = "/".join(path[no +1:])126 prefix_url = "/".join(path[:no + 1]) 127 rest_url = "/".join(path[no + 1:]) 128 128 # if not rest_url.endswith("/"): 129 129 # rest_url += "/" … … 141 141 if pagetree == None: 142 142 pagetree = request.PYLUCID.pagetree 143 143 144 144 pagemeta = self.get_pagemeta(request, pagetree) 145 145 url = pagemeta.get_absolute_url() 146 146 title = pagemeta.title_or_slug() 147 147 148 148 backlist = [{"url": url, "title": title}] 149 149 150 150 parent = pagetree.parent 151 if parent: 151 if parent: 152 152 # insert parent links 153 153 backlist = self.get_backlist(request, parent) + backlist … … 160 160 """ 161 161 The CMS page tree 162 162 163 163 inherited attributes from UpdateInfoBaseModel: 164 164 createtime -> datetime of creation … … 198 198 permitViewGroup = models.ForeignKey(Group, related_name="%(class)s_permitViewGroup", 199 199 help_text="Limit viewable to a group?", 200 null=True, blank=True, 200 null=True, blank=True, 201 201 ) 202 202 permitEditGroup = models.ForeignKey(Group, related_name="%(class)s_permitEditGroup", … … 217 217 218 218 class Meta: 219 unique_together =(("site", "slug", "parent"),)220 219 unique_together = (("site", "slug", "parent"),) 220 221 221 # FIXME: It would be great if we can order by get_absolute_url() 222 222 ordering = ("site", "id", "position") … … 232 232 permitViewGroup = models.ForeignKey(Group, related_name="%(class)s_permitViewGroup", 233 233 help_text="Limit viewable to a group for a complete language section?", 234 null=True, blank=True, 234 null=True, blank=True, 235 235 ) 236 236 … … 250 250 page = models.ForeignKey(PageTree) 251 251 lang = models.ForeignKey(Language) 252 252 253 253 def get_absolute_url(self): 254 254 """ absolute url *with* language code (without domain/host part) """ … … 256 256 page_url = self.page.get_absolute_url() 257 257 return "/" + lang_code + page_url 258 258 259 259 def get_site(self): 260 260 return self.page.site 261 261 262 262 class Meta: 263 263 abstract = True … … 268 268 """ 269 269 Meta data for PageContent or PluginPage 270 270 271 271 inherited attributes from i18nPageTreeBaseModel: 272 272 page -> ForeignKey to PageTree 273 273 lang -> ForeignKey to Language 274 274 get_absolute_url() 275 275 276 276 inherited attributes from UpdateInfoBaseModel: 277 277 createtime -> datetime of creation … … 293 293 permitViewGroup = models.ForeignKey(Group, related_name="%(class)s_permitViewGroup", 294 294 help_text="Limit viewable to a group?", 295 null=True, blank=True, 295 null=True, blank=True, 296 296 ) 297 297 … … 302 302 def __unicode__(self): 303 303 return u"PageMeta for page: '%s' (lang: '%s')" % (self.page.slug, self.lang.code) 304 305 class Meta: 306 unique_together = (("page", "lang"),)304 305 class Meta: 306 unique_together = (("page", "lang"),) 307 307 ordering = ("page", "lang") 308 308 … … 313 313 """ 314 314 A plugin page 315 315 316 316 inherited attributes from i18nPageTreeBaseModel: 317 317 page -> ForeignKey to PageTree 318 318 lang -> ForeignKey to Language 319 319 get_absolute_url() 320 320 321 321 inherited attributes from UpdateInfoBaseModel: 322 322 createtime -> datetime of creation … … 325 325 lastupdateby -> ForeignKey to user who has edited this entry 326 326 """ 327 APP_LABEL_CHOICES = [(app, app) for app in settings.INSTALLED_APPS]328 327 APP_LABEL_CHOICES = [(app, app) for app in settings.INSTALLED_APPS] 328 329 329 pagemeta = models.ForeignKey(PageMeta) 330 330 331 331 app_label = models.CharField(max_length=256, choices=APP_LABEL_CHOICES, 332 332 help_text="The app lable witch is in settings.INSTALLED_APPS" 333 333 ) 334 334 335 335 def title_or_slug(self): 336 336 """ The page title is optional, if not exist, used the slug from the page tree """ 337 337 return self.pagemeta.title or self.page.slug 338 338 339 339 def get_plugin_name(self): 340 340 return self.app_label.split(".")[-1] 341 341 342 342 def save(self, *args, **kwargs): 343 343 if not self.page.type == self.page.PLUGIN_TYPE: … … 345 345 raise AssertionError("Plugin can only exist on a plugin type tree entry!") 346 346 return super(PluginPage, self).save(*args, **kwargs) 347 347 348 348 def __unicode__(self): 349 349 return u"PluginPage '%s' (page: %s)" % (self.app_label, self.page) 350 351 class Meta: 352 unique_together = (("page", "lang"),)350 351 class Meta: 352 unique_together = (("page", "lang"),) 353 353 ordering = ("page", "lang") 354 354 … … 360 360 """ 361 361 Manager class for PageContent model 362 362 363 363 inherited from models.Manager: 364 364 get_or_create() method, witch expected a request object as the first argument. 365 """ 365 """ 366 366 def get_sub_pages(self, pagecontent): 367 367 """ … … 373 373 current_page = pagecontent.page 374 374 sub_pages = PageContent.objects.all().filter(page__parent=current_page, lang=current_lang) 375 return sub_pages 375 return sub_pages 376 376 377 377 … … 392 392 """ 393 393 # IDs used in other parts of PyLucid, too 394 MARKUP_CREOLE = 6395 MARKUP_HTML = 0396 MARKUP_HTML_EDITOR = 1397 MARKUP_TINYTEXTILE = 2398 MARKUP_TEXTILE = 3399 MARKUP_MARKDOWN = 4400 MARKUP_REST = 5394 MARKUP_CREOLE = 6 395 MARKUP_HTML = 0 396 MARKUP_HTML_EDITOR = 1 397 MARKUP_TINYTEXTILE = 2 398 MARKUP_TEXTILE = 3 399 MARKUP_MARKDOWN = 4 400 MARKUP_REST = 5 401 401 402 402 MARKUP_CHOICES = ( … … 411 411 MARKUP_DICT = dict(MARKUP_CHOICES) 412 412 #-------------------------------------------------------------------------- 413 413 414 414 objects = PageContentManager() 415 415 … … 433 433 434 434 class Meta: 435 unique_together = (("page", "lang"),)435 unique_together = (("page", "lang"),) 436 436 ordering = ("page", "lang") 437 437 … … 445 445 """ 446 446 name = models.CharField(max_length=255, help_text="The name of this color scheme.") 447 447 448 448 def update(self, colors): 449 449 assert isinstance(colors, dict) … … 474 474 colors = self.all().filter(colorscheme=colorscheme) 475 475 color_list = colors.values_list('name', 'value') 476 return dict([(name, "#%s" % value) for name, value in color_list])476 return dict([(name, "#%s" % value) for name, value in color_list]) 477 477 478 478 class Color(AutoSiteM2M, UpdateInfoBaseModel): … … 483 483 """ 484 484 objects = ColorManager() 485 485 486 486 colorscheme = models.ForeignKey(ColorScheme) 487 487 name = models.CharField(max_length=128, … … 489 489 ) 490 490 value = ColorValueField(help_text="CSS hex color value.") 491 491 492 492 def save(self, *args, **kwargs): 493 493 self.name = self.name.replace(" ", "_") 494 494 new_name = self.name 495 old_name = Color.objects.get(id=self.id).name 496 if new_name != old_name: 497 # Color name has been changed -> Rename template placeholder in every headfile, too. 498 designs = Design.objects.all().filter(colorscheme=self.colorscheme) 499 for design in designs: 500 headfiles = design.headfiles.all() 501 for headfile in headfiles: 502 if headfile.render != True: # File used no color placeholder 503 continue 504 505 old_content = headfile.content 506 # FIXME: Use flexibler regexp. for this: 507 new_content = old_content.replace("{{ %s }}" % old_name, "{{ %s }}" % new_name) 508 if old_content == new_content: 509 # content not changed?!? 510 user_message_or_warn( 511 "Color '{{ %s }}' not exist in headfile %r" % (old_name, headfile) 512 ) 513 continue 514 515 if settings.DEBUG: 516 user_message_or_warn( 517 "change color name from '%s' to '%s' in %r" % (old_name, new_name, headfile) 518 ) 519 headfile.content = new_content 520 headfile.save() 495 try: 496 old_name = Color.objects.get(id=self.id).name 497 except Color.DoesNotExist: 498 # New color 499 pass 500 else: 501 if new_name != old_name: 502 # Color name has been changed -> Rename template placeholder in every headfile, too. 503 designs = Design.objects.all().filter(colorscheme=self.colorscheme) 504 for design in designs: 505 headfiles = design.headfiles.all() 506 for headfile in headfiles: 507 if headfile.render != True: # File used no color placeholder 508 continue 509 510 old_content = headfile.content 511 # FIXME: Use flexibler regexp. for this: 512 new_content = old_content.replace("{{ %s }}" % old_name, "{{ %s }}" % new_name) 513 if old_content == new_content: 514 # content not changed?!? 515 user_message_or_warn( 516 "Color '{{ %s }}' not exist in headfile %r" % (old_name, headfile) 517 ) 518 continue 519 520 if settings.DEBUG: 521 user_message_or_warn( 522 "change color name from '%s' to '%s' in %r" % (old_name, new_name, headfile) 523 ) 524 headfile.content = new_content 525 headfile.save() 521 526 522 527 return super(Color, self).save(*args, **kwargs) 523 528 524 529 def __unicode__(self): 525 530 return u"Color '%s' #%s (%s)" % (self.name, self.value, self.colorscheme) 526 527 class Meta: 528 unique_together =(("colorscheme", "name"),)531 532 class Meta: 533 unique_together = (("colorscheme", "name"),) 529 534 ordering = ("colorscheme", "name") 530 535 … … 537 542 """ 538 543 Page design: template + CSS/JS files 539 544 540 545 inherited attributes from AutoSiteM2M: 541 546 site -> ManyToManyField to Site 542 547 on_site -> sites.managers.CurrentSiteManager instance 543 548 544 549 inherited attributes from UpdateInfoBaseModel: 545 550 createtime -> datetime of creation … … 549 554 """ 550 555 objects = DesignManager() 551 556 552 557 name = models.CharField(unique=True, max_length=150, help_text="Name of this design combination",) 553 558 template = models.CharField(max_length=128, help_text="filename of the used template for this page") … … 566 571 sites = [site.name for site in self.site.all()] 567 572 return u"Page design '%s' (on sites: %r)" % (self.name, sites) 568 573 569 574 class Meta: 570 575 ordering = ("template",) … … 580 585 db_instance = self.get(filename=filename) 581 586 return headfile.HeadfileLink(filename=db_instance.filename)#, content=db_instance.content) 582 587 583 588 584 589 class EditableHtmlHeadFile(AutoSiteM2M, UpdateInfoBaseModel): 585 590 """ 586 591 Storage for editable static text files, e.g.: stylesheet / javascript. 587 592 588 593 inherited attributes from AutoSiteM2M: 589 594 site -> ManyToManyField to Site 590 595 on_site -> sites.managers.CurrentSiteManager instance 591 596 592 597 inherited attributes from UpdateInfoBaseModel: 593 598 createtime -> datetime of creation … … 597 602 """ 598 603 objects = EditableHtmlHeadFileManager() 599 604 600 605 filepath = models.CharField(max_length=256) 601 606 mimetype = models.CharField(max_length=64) … … 604 609 help_text='Additional html tag attributes (CSS example: media="screen")' 605 610 ) 606 render = models.BooleanField(default =False,611 render = models.BooleanField(default=False, 607 612 help_text="Are there CSS ColorScheme entries in the content?" 608 613 ) 609 614 description = models.TextField(null=True, blank=True) 610 615 content = models.TextField() 611 616 612 617 def get_color_filepath(self, colorscheme): 613 618 """ Colorscheme + filepath """ 614 619 assert isinstance(colorscheme, ColorScheme) 615 620 return os.path.join("ColorScheme_%s" % colorscheme.pk, self.filepath) 616 621 617 622 def get_path(self, colorscheme): 618 623 """ Path for filesystem cache path and link url. """ … … 621 626 self.get_color_filepath(colorscheme) 622 627 ) 623 628 624 629 def get_cachepath(self, colorscheme): 625 630 """ … … 628 633 """ 629 634 return os.path.join(settings.MEDIA_ROOT, self.get_path(colorscheme)) 630 635 631 636 def get_rendered(self, colorscheme): 632 637 color_dict = Color.objects.get_color_dict(colorscheme) 633 return render.render_string_template(self.content, color_dict) 634 638 return render.render_string_template(self.content, color_dict) 639 635 640 def save_cache_file(self, colorscheme): 636 641 """ … … 639 644 """ 640 645 cachepath = self.get_cachepath(colorscheme) 641 646 642 647 def _save_cache_file(auto_create_dir=True): 643 648 rendered_content = self.get_rendered(colorscheme) … … 648 653 except IOError, err: 649 654 if auto_create_dir and err.errno == errno.ENOENT: # No 2: No such file or directory 650 # Try to create the out dir and save the cache file 655 # Try to create the out dir and save the cache file 651 656 path = os.path.dirname(cachepath) 652 657 if not os.path.isdir(path): … … 722 727 723 728 724 729 725 730 class UserProfile(AutoSiteM2M, UpdateInfoBaseModel): 726 731 """ 727 732 Stores additional information about PyLucid users 728 733 http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users 729 734 730 735 Created via post_save signal, if a new user created. 731 736 732 737 inherited attributes from AutoSiteM2M: 733 738 site -> ManyToManyField to Site … … 735 740 """ 736 741 user = models.ForeignKey(User, unique=True, related_name="%(class)s_user") 737 742 738 743 sha_login_checksum = models.CharField(max_length=192, 739 744 help_text="Checksum for PyLucid JS-SHA-Login" … … 742 747 help_text="Salt value for PyLucid JS-SHA-Login" 743 748 ) 744 749 745 750 # TODO: Overwrite help_text: 746 751 # site = models.ManyToManyField(Site, 747 752 # help_text="User can access only these sites." 748 753 # ) 749 754 750 755 def set_sha_login_password(self, raw_password): 751 756 """ … … 766 771 sites = self.site.all() 767 772 return ", ".join([site.name for site in sites]) 768 773 769 774 class Meta: 770 775 ordering = ("user",) … … 775 780 def cache_headfiles(sender, **kwargs): 776 781 """ 777 One colorscheme was changes: resave all cache headfiles with new color values. 782 One colorscheme was changes: resave all cache headfiles with new color values. 778 783 """ 779 784 colorscheme = kwargs["instance"] … … 784 789 for headfile in headfiles: 785 790 headfile.save_cache_file(colorscheme) 786 791 787 792 signals.post_save.connect(cache_headfiles, sender=ColorScheme) 788 793 … … 793 798 """ signal handler: creating user profile, after a new user created. """ 794 799 user = kwargs["instance"] 795 800 796 801 userprofile, created = UserProfile.objects.get_or_create(user=user) 797 802 if created: 798 803 user_message_or_warn("UserProfile entry for user '%s' created." % user) 799 # 804 # 800 805 # if not user.is_superuser: # Info: superuser can automaticly access all sites 801 806 # site = Site.objects.get_current() 802 807 # userprofile.site.add(site) 803 # user_message_or_warn("Add site '%s' to '%s' UserProfile." % (site.name, user)) 808 # user_message_or_warn("Add site '%s' to '%s' UserProfile." % (site.name, user)) 804 809 805 810 signals.post_save.connect(create_user_profile, sender=User) … … 826 831 # Use the original method to set the django User password: 827 832 orig_set_password(user, raw_password) 828 833 829 834 userprofile, created = UserProfile.objects.get_or_create(user=user) 830 835 if created: … … 836 841 837 842 838 # replace the method 843 # replace the method 839 844 User.set_password = set_password