def settings_privacy(request): from booki.utils import config if request.method == "POST": frm = PrivacyForm(request.POST, request.FILES) if request.POST["submit"] == _("Cancel"): return HttpResponseRedirect(reverse("control_settings")) if frm.is_valid(): config.setConfiguration("FREE_REGISTRATION", frm.cleaned_data["user_register"]) config.setConfiguration("ADMIN_CREATE_BOOKS", frm.cleaned_data["create_books"]) config.setConfiguration("ADMIN_IMPORT_BOOKS", frm.cleaned_data["import_books"]) try: config.saveConfiguration() messages.success(request, _("Successfuly saved changes.")) except config.ConfigurationError: messages.warning(request, _("Unknown error while saving changes.")) return HttpResponseRedirect(reverse("control_settings")) else: frm = PrivacyForm( initial={ "user_register": config.getConfiguration("FREE_REGISTRATION"), "create_books": config.getConfiguration("ADMIN_CREATE_BOOKS"), "import_books": config.getConfiguration("ADMIN_IMPORT_BOOKS"), } ) return render_to_response( "booktypecontrol/settings_privacy.html", {"request": request, "admin_options": ADMIN_OPTIONS, "form": frm} )
def handle(self, *args, **options): if not hasattr(settings, 'BOOKTYPE_CONFIG'): raise CommandError('Does not have BOOKTYPE_CONFIG in settings.py file.') if len(args) != 2: raise CommandError("You must specify variable name and value.") key = args[0] value = args[1] if options['integer']: try: value = int(value) except ValueError: raise CommandError("I don't think this %s is a number!" % value) if options['float']: try: value = float(value) except ValueError: raise CommandError("I don't think this %s is a number!" % value) if options['as_json']: try: value = json.loads(value) except ValueError: raise CommandError("Not a valid JSON string.") if options['append']: # ovo neshto ne radi sa as_jsonom lst = config.getConfiguration(key, []) if type(lst) == type([]): lst.append(value) config.setConfiguration(key, lst) else: raise CommandError("Can not append to something that is not a list") elif options['remove']: lst = config.getConfiguration(key, []) if type(lst) == type([]): try: lst.remove(value) except ValueError: raise CommandError("I can't see it!") config.setConfiguration(key, lst) else: raise CommandError("Can not append to something that is not a list") else: config.setConfiguration(key, value) try: config.saveConfiguration() except config.ConfigurationError: raise CommandError("Could not save the file.")
def settings_description(request): if request.method == "POST": frm = SiteDescriptionForm(request.POST, request.FILES) if request.POST["submit"] == _("Cancel"): return HttpResponseRedirect(reverse("control_settings")) if frm.is_valid(): from booki.utils import config config.setConfiguration("BOOKTYPE_SITE_NAME", frm.cleaned_data["title"]) config.setConfiguration("BOOKTYPE_SITE_TAGLINE", frm.cleaned_data["tagline"]) if request.FILES.has_key("favicon"): from booki.utils import misc import shutil # just check for any kind of silly error try: fh, fname = misc.saveUploadedAsFile(request.FILES["favicon"]) shutil.move(fname, "%s/favicon.ico" % settings.STATIC_ROOT) config.setConfiguration("BOOKTYPE_SITE_FAVICON", "%s/static/favicon.ico" % settings.BOOKI_URL) except: pass try: config.saveConfiguration() messages.success(request, _("Successfuly saved settings.")) except config.ConfigurationError: messages.warning(request, _("Unknown error while saving changes.")) return HttpResponseRedirect(reverse("control_settings")) else: from booki.utils import config frm = SiteDescriptionForm( initial={ "title": config.getConfiguration("BOOKTYPE_SITE_NAME"), "tagline": config.getConfiguration("BOOKTYPE_SITE_TAGLINE"), } ) return render_to_response( "booktypecontrol/settings_description.html", {"request": request, "admin_options": ADMIN_OPTIONS, "form": frm}, context_instance=RequestContext(request), )
def view_profile(request, username): """ Django View. Shows user profile. Right now, this is just basics. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. @todo: Check if user exists. """ from django.contrib.auth.models import User from booki.editor import models try: user = User.objects.get(username=username) except User.DoesNotExist: return pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) if request.user.username == username: books = models.Book.objects.filter(owner=user) else: if request.user.is_authenticated() and request.user.is_superuser: books = models.Book.objects.filter(owner=user) else: books = models.Book.objects.filter(owner=user, hidden=False) groups = user.members.all() from django.utils.html import escape userDescription = escape(user.get_profile().description) admin_create = config.getConfiguration('ADMIN_CREATE_BOOKS') admin_import = config.getConfiguration('ADMIN_IMPORT_BOOKS') if request.user.is_superuser: admin_create = False admin_import = False return render_to_response('account/view_profile.html', {"request": request, "user": user, "admin_create": admin_create, "admin_import": admin_import, "user_description": '<br/>'.join(userDescription.replace('\r','').split('\n')), "books": books, "groups": groups})
def isBookLimitReached(): """ Checks if maximum number of books is reaced. @rtype text: C{book} @param: Returns True if maximum number of books is reached """ from booki.utils import config from booki.editor import models maxBooks = config.getConfiguration('BOOKTYPE_MAX_BOOKS') if not isinstance(maxBooks, int): # We should show some kind of warning here return False # 0 means unlimited and that is the default value if maxBooks == 0: return False # get list of all active books numBooks = models.Book.objects.all().count() if numBooks >= maxBooks: return True return False
def isUserLimitReached(): """ Checks if maximum number of user is reached. @rtype text: C{book} @param: Returns True if maximum number of users is reached """ from booki.utils import config from django.contrib.auth.models import User maxUsers = config.getConfiguration('BOOKTYPE_MAX_USERS') if not isinstance(maxUsers, int): # We should show some kind of warning here return False # 0 means unlimited and that is the default value if maxUsers == 0: return False # get list of all active accounts numUsers = User.objects.filter(is_active=True).count() if numUsers >= maxUsers: return True return False
def booki_site_metadata(): from booki.utils import config import cgi s = '' # probably should add namespace to html tag name = config.getConfiguration('BOOKTYPE_SITE_NAME', None) if name: s += '<meta property="og:site_name" content="%s"/>' % cgi.escape(name, True) tagline = config.getConfiguration('BOOKTYPE_SITE_TAGLINE', None) if tagline: s += '<meta itemprop="description" content="%s"/>' % cgi.escape(tagline, True) return s
def settings_publishing_defaults(request): from booki.utils import config data = { "book_css": config.getConfiguration("BOOKTYPE_CSS_BOOK", ""), "ebook_css": config.getConfiguration("BOOKTYPE_CSS_EBOOK", ""), "lulu_css": config.getConfiguration("BOOKTYPE_CSS_LULU", ""), "pdf_css": config.getConfiguration("BOOKTYPE_CSS_PDF", ""), "odt_css": config.getConfiguration("BOOKTYPE_CSS_ODT", ""), } if request.method == "POST": frm = PublishingDefaultsForm(request.POST, request.FILES) if request.POST["submit"] == _("Cancel"): return HttpResponseRedirect(reverse("control_settings")) if frm.is_valid(): if frm.cleaned_data["book_css"] != data["book_css"]: config.setConfiguration("BOOKTYPE_CSS_BOOK", frm.cleaned_data["book_css"]) if frm.cleaned_data["ebook_css"] != data["ebook_css"]: config.setConfiguration("BOOKTYPE_CSS_EBOOK", frm.cleaned_data["ebook_css"]) if frm.cleaned_data["lulu_css"] != data["lulu_css"]: config.setConfiguration("BOOKTYPE_CSS_LULU", frm.cleaned_data["lulu_css"]) if frm.cleaned_data["pdf_css"] != data["pdf_css"]: config.setConfiguration("BOOKTYPE_CSS_PDF", frm.cleaned_data["pdf_css"]) if frm.cleaned_data["odt_css"] != data["odt_css"]: config.setConfiguration("BOOKTYPE_CSS_ODT", frm.cleaned_data["odt_css"]) try: config.saveConfiguration() messages.success(request, _("Successfuly saved changes.")) except config.ConfigurationError: messages.warning(request, _("Unknown error while saving changes.")) return HttpResponseRedirect(reverse("control_settings")) else: frm = PublishingDefaultsForm(initial=data) return render_to_response( "booktypecontrol/settings_publishing_defaults.html", {"request": request, "admin_options": ADMIN_OPTIONS, "form": frm}, )
def booki_site_metadata(): from booki.utils import config import cgi s = '' # probably should add namespace to html tag name = config.getConfiguration('BOOKTYPE_SITE_NAME', None) if name: s += '<meta property="og:site_name" content="%s"/>' % cgi.escape( name, True) tagline = config.getConfiguration('BOOKTYPE_SITE_TAGLINE', None) if tagline: s += '<meta name="description" content="%s"/>' % cgi.escape( tagline, True) return s
def settings_book_create(request): if request.method == "POST": frm = BookCreateForm(request.POST, request.FILES) if request.POST["submit"] == _("Cancel"): return HttpResponseRedirect(reverse("control_settings")) if frm.is_valid(): from booki.utils import config config.setConfiguration("CREATE_BOOK_VISIBLE", frm.cleaned_data["visible"]) if frm.cleaned_data["license"]: config.setConfiguration("CREATE_BOOK_LICENSE", frm.cleaned_data["license"].abbrevation) else: config.setConfiguration("CREATE_BOOK_LICENSE", "") try: config.saveConfiguration() messages.success(request, _("Successfuly saved settings.")) except config.ConfigurationError: messages.warning(request, _("Unknown error while saving changes.")) return HttpResponseRedirect(reverse("control_settings")) else: from booki.utils import config _l = config.getConfiguration("CREATE_BOOK_LICENSE") if _l and _l != "": try: license = models.License.objects.get(abbrevation=_l) except models.License.DoesNotExist: license = None else: license = None frm = BookCreateForm(initial={"visible": config.getConfiguration("CREATE_BOOK_VISIBLE"), "license": license}) return render_to_response( "booktypecontrol/settings_book_create.html", {"request": request, "admin_options": ADMIN_OPTIONS, "form": frm}, context_instance=RequestContext(request), )
def settings_frontpage(request): from booki.utils import config staticRoot = settings.BOOKI_ROOT if request.method == "POST": frm = FrontpageForm(request.POST, request.FILES) if request.POST["submit"] == _("Cancel"): return HttpResponseRedirect(reverse("control_settings")) if frm.is_valid(): config.setConfiguration("BOOKTYPE_FRONTPAGE_HISTORY", frm.cleaned_data["show_changes"]) import os.path, os if not os.path.exists("%s/templates/portal/" % staticRoot): os.makedirs("%s/templates/portal/" % staticRoot) try: f = open("%s/templates/portal/welcome_message.html" % staticRoot, "w") textData = frm.cleaned_data["description"] textData = textData.replace("{%", "").replace("%}", "").replace("{{", "").replace("}}", "") f.write(textData.encode("utf8")) f.close() messages.success(request, _("Successfuly saved changes.")) config.saveConfiguration() except IOError: messages.warning(request, _("Error while saving changes")) except config.ConfigurationError: messages.warning(request, _("Unknown error while saving changes.")) return HttpResponseRedirect(reverse("control_settings")) else: try: f = open("%s/templates/portal/welcome_message.html" % staticRoot, "r") textContent = unicode(f.read(), "utf8") f.close() except IOError: textContent = "" frm = FrontpageForm( initial={ "show_changes": config.getConfiguration("BOOKTYPE_FRONTPAGE_HISTORY", True), "description": textContent, } ) return render_to_response( "booktypecontrol/settings_frontpage.html", {"request": request, "admin_options": ADMIN_OPTIONS, "form": frm} )
def booki_site_name(): from django.core.urlresolvers import reverse from django.conf import settings from booki.utils import config frontpageURL = reverse('frontpage') name = config.getConfiguration('BOOKTYPE_SITE_NAME', None) if name: s = '<div class="logotext"><a href="%s%s">%s</a> </div>' % (settings.BOOKI_URL, frontpageURL, name) else: s = '<div class="logo"><a href="%s%s"></a></div>' % (settings.BOOKI_URL, frontpageURL) return s
def settings_publishing(request): from booki.utils import config publishOptions = config.getConfiguration("PUBLISH_OPTIONS") if request.method == "POST": frm = PublishingForm(request.POST, request.FILES) if request.POST["submit"] == _("Cancel"): return HttpResponseRedirect(reverse("control_settings")) if frm.is_valid(): opts = [] # a bit silly way to create a list if frm.cleaned_data["publish_book"]: opts.append("book") if frm.cleaned_data["publish_ebook"]: opts.append("ebook") if frm.cleaned_data["publish_lulu"]: opts.append("lulu") if frm.cleaned_data["publish_pdf"]: opts.append("pdf") if frm.cleaned_data["publish_odt"]: opts.append("odt") config.setConfiguration("PUBLISH_OPTIONS", opts) try: config.saveConfiguration() messages.success(request, _("Successfuly saved changes.")) except config.ConfigurationError: messages.warning(request, _("Unknown error while saving changes.")) return HttpResponseRedirect(reverse("control_settings")) else: frm = PublishingForm( initial={ "publish_book": "book" in publishOptions, "publish_ebook": "ebook" in publishOptions, "publish_lulu": "lulu" in publishOptions, "publish_pdf": "pdf" in publishOptions, "publish_odt": "odt" in publishOptions, } ) return render_to_response( "booktypecontrol/settings_publishing.html", {"request": request, "admin_options": ADMIN_OPTIONS, "form": frm} )
def booki_site_favicon(): from django.core.urlresolvers import reverse from django.conf import settings from booki.utils import config import cgi frontpageURL = reverse('frontpage') favicon = config.getConfiguration('BOOKTYPE_SITE_FAVICON', None) if favicon: s = '<link rel="SHORTCUT ICON" href="%s" type="image/x-icon">' % cgi.escape(favicon, True) else: s = '<link rel="SHORTCUT ICON" href="%s/site_static/images/favicon.ico" type="image/x-icon">' % settings.BOOKI_URL return s
def booki_site_favicon(): from django.core.urlresolvers import reverse from django.conf import settings from booki.utils import config import cgi frontpageURL = reverse('frontpage') favicon = config.getConfiguration('BOOKTYPE_SITE_FAVICON', None) if favicon: s = '<link rel="SHORTCUT ICON" href="%s" type="image/x-icon">' % cgi.escape( favicon, True) else: s = '<link rel="SHORTCUT ICON" href="%s/site_static/images/favicon.ico" type="image/x-icon">' % settings.BOOKI_URL return s
def booki_site_name(): from django.core.urlresolvers import reverse from django.conf import settings from booki.utils import config frontpageURL = reverse('frontpage') name = config.getConfiguration('BOOKTYPE_SITE_NAME', None) if name: s = '<div class="logotext"><a href="%s%s">%s</a> </div>' % ( settings.BOOKI_URL, frontpageURL, name) else: s = '<div class="logo"><a href="%s%s"></a></div>' % ( settings.BOOKI_URL, frontpageURL) return s
def view_frontpage(request): """ Django View. This is main Booktype Front Page. @type request: C{django.http.HttpRequest} @param request: Client Request object """ from booki.utils import config showHistory = config.getConfiguration('BOOKTYPE_FRONTPAGE_HISTORY', True) if showHistory: activityHistory = models.BookHistory.objects.filter(kind__in=[1, 10], book__hidden=False).order_by('-modified')[:20] else: activityHistory = [] return render_to_response('portal/frontpage.html', {"request": request, "activity_history": activityHistory, "show_history": showHistory, "title": "Booktype"})
def create_book(request, username): """ Django View. Show content for Create Book dialog and creates book. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. """ from django.contrib.auth.models import User try: user = User.objects.get(username=username) except User.DoesNotExist: try: return pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) except: transaction.rollback() finally: transaction.commit() if not request.user.is_authenticated(): try: return pages.ErrorPage(request, "errors/no_permissions.html") except: transaction.rollback() finally: transaction.commit() from booki.utils.book import checkBookAvailability, createBook from booki.editor import models book_visible = config.getConfiguration('CREATE_BOOK_VISIBLE') book_license = config.getConfiguration('CREATE_BOOK_LICENSE') admin_create = config.getConfiguration('ADMIN_CREATE_BOOKS') if request.user.is_superuser: admin_create = False if request.GET.get("q", "") == "check": from booki.utils.json_wrapper import json data = {"available": checkBookAvailability(request.GET.get('bookname', '').strip())} try: return HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() finally: transaction.commit() if request.method == 'POST' and admin_create == False: book = None try: # hidden on # description # license # title # cover book = createBook(request.user, request.POST.get('title')) lic = models.License.objects.get(abbrevation=request.POST.get('license')) book.license = lic book.description = request.POST.get('description', '') if request.POST.get("hidden", "") == "on": is_hidden = True else: is_hidden = False book.hidden = is_hidden from django.core.files import File if request.FILES.has_key('cover'): # TODO: Show some kind of error message to the user from booki.utils import misc import os try: fh, fname = misc.saveUploadedAsFile(request.FILES['cover']) book.setCover(fname) os.unlink(fname) except: pass book.save() except: transaction.rollback() else: transaction.commit() try: return render_to_response('account/create_book_redirect.html', {"request": request, "user": user, "book": book}) except: transaction.rollback() finally: transaction.commit() from booki.editor.models import License licenses = License.objects.all().order_by('name') try: return render_to_response('account/create_book.html', {"request": request, "book_visible": book_visible, "book_license": book_license, "admin_create": admin_create, "licenses": licenses, "user": user}) except: transaction.rollback() finally: transaction.commit()
def importFeed(document, conf): """ Imports content of Wordpress export into Booktype. """ # To create a book we use "createBook" function. It will do good part of magic for us in the background. # We have to provide: # - owner of the book; every book must have an owner # - book title; this is full book name # - book status; every book has a status, let us just use "new" for now # - book url; book must have unique name and in Booktype world it is book url name from booki.utils.book import createBook book = createBook(conf["user"], conf["bookTitle"], status="new", bookURL=conf["bookTitleURL"]) # We use config API to check if books are by default visible or not isVisible = config.getConfiguration("CREATE_BOOK_VISIBLE", True) book.hidden = not isVisible book.save() # "createBook" function has already created default list of statuses. Let's just fetch "new" status because # we will need it for Chapters later stat = models.BookStatus.objects.filter(book=book, name="new")[0] # What is default URL for Wordpress blog wpLink = document["feed"]["link"] attachments = [] for item in document["items"]: # We only care about posts which have "publish" status. Ignore everything else for now. if item["wp_status"] != u"publish": continue chapterTitle = item["title"] print ">> ", chapterTitle # So... let's clean our Wordpress post a bit. Here we ASSUME that empty line is used to separate paragraphs in Wordpress post. content = item["content"][0]["value"].replace("\r\n", "\n") content = "\n".join(["<p>%s</p>" % p for p in content.split("\n\n") if p.strip() != ""]) # Every Booktype chapter starts with Chapter title embded in H2 tag. content = u"<h2>%s</h2>%s" % (chapterTitle, content) tree = html.document_fromstring(content) for e in tree.iter(): # We only care about images now if e.tag == "img": src = e.get("src") if src: if src.startswith("/"): src = wpLink + src # We don't need to download picture if it was already downloaed if not src in attachments: attachments.append(src) u = urlparse.urlsplit(src) # Get the file name and take care of funny stuff like %20 in file names fileName = os.path.basename(urllib.unquote(u.path)) print " >> ", fileName # Download image data = downloadFile(src) # Let us create this attachment if we managed to download something if data: # Create new Attachment. "book" argument is part of legacy here, we really should care only about "version". # Expect this to be removed in the future. Also, every Attachment can have different status. Not that it is # used anywhere at the moment, but it has to be here. att = models.Attachment(book=book, version=book.version, status=stat) # We use standard method for saving the data. f2 = File(StringIO(data)) f2.size = len(data) att.attachment.save(fileName, f2, save=True) # If filename with the same name already exists then Django will add prefix to the name. # For instance: Image.jpg would become Image_1.jpg. That is why we check the new name. fileName = os.path.basename(att.attachment.path) # Set whatever we got as a new attachment name. Also notice all images are referenced as # "static/image.jpg" in Booktype so we have to change the source also. e.set("src", "static/%s" % fileName) content = etree.tostring(tree, encoding="UTF-8", method="html") # Create new chapter. New chapter will be in "Hold chapters". If you want it to be in "Table of contents" you would # need to do some extra magic. But we don't care about it now. We also don't really care about writing anything to # log files... now = datetime.datetime.now() chapter = models.Chapter( book=book, version=book.version, url_title=bookiSlugify(chapterTitle), title=chapterTitle, status=stat, content=content, created=now, modified=now, ) chapter.save()
def booki_anyone_register(object): from booki.utils import config return config.getConfiguration('FREE_REGISTRATION', True)
def handle(self, *args, **options): if not hasattr(settings, 'BOOKTYPE_CONFIG'): raise CommandError( 'Does not have BOOKTYPE_CONFIG in settings.py file.') if len(args) != 2: raise CommandError("You must specify variable name and value.") key = args[0] value = args[1] if options['integer']: try: value = int(value) except ValueError: raise CommandError("I don't think this %s is a number!" % value) if options['float']: try: value = float(value) except ValueError: raise CommandError("I don't think this %s is a number!" % value) if options['as_json']: try: value = json.loads(value) except ValueError: raise CommandError("Not a valid JSON string.") if options['append']: # ovo neshto ne radi sa as_jsonom lst = config.getConfiguration(key, []) if type(lst) == type([]): lst.append(value) config.setConfiguration(key, lst) else: raise CommandError( "Can not append to something that is not a list") elif options['remove']: lst = config.getConfiguration(key, []) if type(lst) == type([]): try: lst.remove(value) except ValueError: raise CommandError("I can't see it!") config.setConfiguration(key, lst) else: raise CommandError( "Can not append to something that is not a list") else: config.setConfiguration(key, value) try: config.saveConfiguration() except config.ConfigurationError: raise CommandError("Could not save the file.")
def view_profile(request, username): """ Django View. Shows user profile. Right now, this is just basics. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. @todo: Check if user exists. """ from django.contrib.auth.models import User from booki.editor import models from booki.utils.misc import isBookLimitReached try: user = User.objects.get(username=username) except User.DoesNotExist: try: resp = pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) except: transaction.rollback() raise else: transaction.commit() return resp notification_filter = '' if request.user.username == username: #books = models.Book.objects.filter(owner=user) books = models.Book.objects.raw('select * from editor_book where group_id in' ' (select bookigroup_id from editor_bookigroup_members where user_id=%s)' , (user.id,)) endpoint = get_endpoint_or_none("@"+user.username) if endpoint: endpoint_config = endpoint.get_config() if endpoint_config: notification_filter = endpoint_config.notification_filter else: if request.user.is_authenticated() and request.user.is_superuser: books = models.Book.objects.filter(owner=user) else: books = models.Book.objects.raw('select * from editor_book where group_id in' ' (select bookigroup_id from editor_bookigroup_members where user_id=%s)' , (user.id,)) #books = models.Book.objects.filter(owner=user, hidden=False) groups = user.members.all() from django.utils.html import escape userDescription = escape(user.get_profile().description) admin_create = config.getConfiguration('ADMIN_CREATE_BOOKS') admin_import = config.getConfiguration('ADMIN_IMPORT_BOOKS') if request.user.is_superuser: admin_create = False admin_import = False try: resp = render_to_response('account/view_profile.html', {"request": request, "user": user, "admin_create": admin_create, "admin_import": admin_import, "user_description": '<br/>'.join(userDescription.replace('\r','').split('\n')), "books": books, "limit_reached": isBookLimitReached(), "notification_filter": notification_filter, "groups": groups}) except: transaction.rollback() raise else: transaction.commit() return resp
def create_book(request, username): """ Django View. Show content for Create Book dialog and creates book. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. """ import os from glob import glob import datetime from xml.dom import minidom from django.contrib.auth.models import User from booki.utils.misc import isBookLimitReached try: user = User.objects.get(username=username) except User.DoesNotExist: try: resp = pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) except: transaction.rollback() raise else: transaction.commit() return resp if isBookLimitReached() or not request.user.is_authenticated(): try: resp = pages.ErrorPage(request, "errors/no_permissions.html") except: transaction.rollback() raise else: transaction.commit() return resp from booki.utils.book import checkBookAvailability, createBook from booki.editor import models book_visible = config.getConfiguration('CREATE_BOOK_VISIBLE') book_license = config.getConfiguration('CREATE_BOOK_LICENSE') admin_create = config.getConfiguration('ADMIN_CREATE_BOOKS') templates_source = config.getConfiguration('BOOK_TYPES_DIR') if request.user.is_superuser: admin_create = False if request.GET.get("q", "") == "check": from booki.utils.json_wrapper import json data = {"available": checkBookAvailability(request.GET.get('bookname', '').strip())} try: resp = HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() raise else: transaction.commit() return resp if request.method == 'POST' and admin_create == False: book = None try: # hidden on # description # license # title # cover x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[-1].strip() else: ip = request.META.get('REMOTE_ADDR') book = createBook(request.user, request.POST.get('title'), ip) lic = models.License.objects.get(abbrevation=request.POST.get('license')) book.license = lic book.description = request.POST.get('description', '') if request.POST.get("hidden", "") == "on": is_hidden = True else: is_hidden = False book.hidden = is_hidden from django.core.files import File if request.FILES.has_key('cover'): # TODO: Show some kind of error message to the user from booki.utils import misc import os try: fh, fname = misc.saveUploadedAsFile(request.FILES['cover']) book.setCover(fname) os.unlink(fname) except: pass book.save() book_version = book.getVersion() tf = request.POST.get('template', '') try: xmldoc = minidom.parse(tf) chapters = xmldoc.getElementsByTagName('chapter') except: chapters = [] for chapter in chapters: chapter_title = chapter.attributes['title'].value chapter_content = u'<h1>{}</h1>'.format(chapter.attributes['content'].value) url_title = bookiSlugify(chapter_title) status = models.BookStatus.objects.filter(book=book).order_by("-weight")[0] chapter_o = models.Chapter(book=book, version = book_version, url_title = url_title, title = chapter_title, status = status, content = chapter_content, created = datetime.datetime.now(), modified = datetime.datetime.now()) chapter_o.save() toc_items = len(book_version.getTOC()) + 1 for itm in models.BookToc.objects.filter(version=book_version, book=book).order_by("-weight"): itm.weight = toc_items itm.save() toc_items -= 1 tc = models.BookToc(version=book_version, book = book, name = chapter_title, chapter = chapter_o, weight = 1, typeof = 1) tc.save() except: lines = traceback.format_exc().split('\n') for line in lines: print line transaction.rollback() else: transaction.commit() try: resp = render_to_response('account/create_book_redirect.html', {"request": request, "user": user, "book": book}) except: transaction.rollback() raise else: transaction.commit() return resp from booki.editor.models import License licenses = License.objects.all().order_by('name') try: template_files = glob(os.path.join(templates_source, '*.xml')) except: template_files = [] templates = [{'name': 'Vac\xc3\xado', 'file': '/'}] for tf in template_files: print 'parse ' + tf xmldoc = minidom.parse(tf) print 'ok' tpltag = xmldoc.getElementsByTagName('template')[0] template = {} template['name'] = tpltag.attributes['title'].value template['file'] = tf templates.append(template) try: resp = render_to_response('account/create_book.html', {"request": request, "book_visible": book_visible, "book_license": book_license, "admin_create": admin_create, "licenses": licenses, 'templates': templates, "user": user}) except: transaction.rollback() raise else: transaction.commit() return resp
def signin(request): """ Django View. Gets called when user wants to signin or create new account. @type request: C{django.http.HttpRequest} @param request: Django Request """ from booki.utils.json_wrapper import simplejson from booki.editor.models import BookiGroup from django.core.exceptions import ObjectDoesNotExist from django.contrib import auth if request.POST.get("ajax", "") == "1": ret = {"result": 0} if request.POST.get("method", "") == "register" and config.getConfiguration('FREE_REGISTRATION'): def _checkIfEmpty(key): return request.POST.get(key, "").strip() == "" def _doChecksForEmpty(): if _checkIfEmpty("username"): return 2 if _checkIfEmpty("email"): return 3 if _checkIfEmpty("password") or _checkIfEmpty("password2"): return 4 if _checkIfEmpty("fullname"): return 5 return 0 ret["result"] = _doChecksForEmpty() if ret["result"] == 0: # if there was no errors import re def _doCheckValid(): # check if it is valid username # - from 2 to 20 characters long # - word, number, ., _, - mtch = re.match('^[\w\d\_\.\-]{2,20}$', request.POST.get("username", "").strip()) if not mtch: return 6 # check if it is valid email if not bool(email_re.match(request.POST["email"].strip())): return 7 if request.POST.get("password", "") != request.POST.get("password2", "").strip(): return 8 if len(request.POST.get("password", "").strip()) < 6: return 9 if len(request.POST.get("fullname", "").strip()) > 30: return 11 # check if this user exists try: u = auth.models.User.objects.get(username=request.POST.get("username", "").strip()) return 10 except auth.models.User.DoesNotExist: pass return 0 ret["result"] = _doCheckValid() if ret["result"] == 0: ret["result"] = 1 user = None try: user = auth.models.User.objects.create_user(username=request.POST["username"].strip(), email=request.POST["email"].strip(), password=request.POST["password"].strip()) except IntegrityError: ret["result"] = 10 # this is not a good place to fire signal, but i need password for now # should create function createUser for future use if user: import booki.account.signals booki.account.signals.account_created.send(sender = user, password = request.POST["password"]) user.first_name = request.POST["fullname"].strip() try: user.save() # groups for groupName in simplejson.loads(request.POST.get("groups")): if groupName.strip() != '': sid = transaction.savepoint() try: group = BookiGroup.objects.get(url_name=groupName) group.members.add(user) except: transaction.savepoint_rollback(sid) else: transaction.savepoint_commit(sid) user2 = auth.authenticate(username=request.POST["username"].strip(), password=request.POST["password"].strip()) auth.login(request, user2) except: transaction.rollback() ret["result"] = 666 else: transaction.commit() if request.POST.get("method", "") == "signin": user = auth.authenticate(username=request.POST["username"].strip(), password=request.POST["password"].strip()) if user: auth.login(request, user) ret["result"] = 1 from django.core.urlresolvers import reverse ret["redirect"] = reverse('view_profile', args=[user.username]) else: try: usr = auth.models.User.objects.get(username=request.POST["username"]) # User does exist. Must be wrong password then ret["result"] = 3 except auth.models.User.DoesNotExist: # User does not exist ret["result"] = 2 transaction.commit() return HttpResponse(simplejson.dumps(ret), mimetype="text/json") from django.core.urlresolvers import reverse redirect = request.GET.get('redirect', '') if(redirect == reverse('frontpage')): redirect = '' if request.GET.get('next', None): redirect = request.GET.get('next') joinGroups = [] for groupName in request.GET.getlist("group"): try: joinGroups.append(BookiGroup.objects.get(url_name=groupName)) except BookiGroup.DoesNotExist: pass try: return render_to_response('account/signin.html', {"request": request, 'redirect': redirect, 'joingroups': joinGroups}) except: transaction.rollback() finally: transaction.commit()
def forgotpassword(request): """ Django View. Gets called when user wants to change password he managed to forget. @type request: C{django.http.HttpRequest} @param request: Django Request """ from booki.utils.json_wrapper import simplejson from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth.models import User if request.POST.get("ajax", "") == "1": ret = {"result": 0} usr = None if request.POST.get("method", "") == "forgot_password": def _checkIfEmpty(key): return request.POST.get(key, "").strip() == "" def _doChecksForEmpty(): if _checkIfEmpty("username"): return 2 return 0 ret["result"] = _doChecksForEmpty() if ret["result"] == 0: usersToEmail = list(User.objects.filter(Q(username=request.POST.get("username", "")) | Q(email=request.POST.get("username", "")))) for usr in usersToEmail: from booki.account import models as account_models def generateSecretCode(): import string from random import choice return ''.join([choice(string.letters + string.digits) for i in range(30)]) secretcode = generateSecretCode() account_models = account_models.UserPassword() account_models.user = usr account_models.remote_useragent = request.META.get('HTTP_USER_AGENT','') account_models.remote_addr = request.META.get('REMOTE_ADDR','') account_models.remote_host = request.META.get('REMOTE_HOST','') account_models.secretcode = secretcode # In case of an error we really should not send email to user and do rest of the procedure try: account_models.save() except: transaction.rollback() else: transaction.commit() THIS_BOOKI_SERVER = config.getConfiguration('THIS_BOOKI_SERVER') body = render_to_string('account/password_reset_email.html', dict(secretcode=secretcode, hostname=THIS_BOOKI_SERVER)) from django.core.mail import EmailMessage msg = EmailMessage(_('Reset password'), body, settings.REPORT_EMAIL_USER, [usr.email]) msg.content_subtype = 'html' try: msg.send() except: ret["result"] = 4 if len(usersToEmail) == 0: ret["result"] = 3 # Do we need rollback for this?! try: resp = HttpResponse(simplejson.dumps(ret), mimetype="text/json") except: transaction.rollback() raise else: transaction.commit() return resp # Do we need commit for this?! try: resp = render_to_response('account/forgot_password.html', {"request": request}) except: transaction.rollback() raise else: transaction.commit() return resp
def signin(request): """ Django View. Gets called when user wants to signin or create new account. @type request: C{django.http.HttpRequest} @param request: Django Request """ from booki.utils.json_wrapper import simplejson from booki.utils.misc import isUserLimitReached from booki.editor.models import BookiGroup from django.core.exceptions import ObjectDoesNotExist from django.contrib import auth limitReached = isUserLimitReached() if request.POST.get("ajax", "") == "1": ret = {"result": 0} if request.POST.get("method", "") == "register" and config.getConfiguration( 'FREE_REGISTRATION') and not limitReached: def _checkIfEmpty(key): return request.POST.get(key, "").strip() == "" def _doChecksForEmpty(): if _checkIfEmpty("username"): return 2 if _checkIfEmpty("email"): return 3 if _checkIfEmpty("password") or _checkIfEmpty("password2"): return 4 if _checkIfEmpty("fullname"): return 5 return 0 ret["result"] = _doChecksForEmpty() if ret["result"] == 0: # if there was no errors import re def _doCheckValid(): # check if it is valid username # - from 2 to 20 characters long # - word, number, ., _, - mtch = re.match('^[\w\d\_\.\-]{2,20}$', request.POST.get("username", "").strip()) if not mtch: return 6 # check if it is valid email if not bool(email_re.match(request.POST["email"].strip())): return 7 if request.POST.get("password", "") != request.POST.get( "password2", "").strip(): return 8 if len(request.POST.get("password", "").strip()) < 6: return 9 if len(request.POST.get("fullname", "").strip()) > 30: return 11 # check if this user exists try: u = auth.models.User.objects.get( username=request.POST.get("username", "").strip()) return 10 except auth.models.User.DoesNotExist: pass return 0 ret["result"] = _doCheckValid() if ret["result"] == 0: ret["result"] = 1 user = None try: user = auth.models.User.objects.create_user( username=request.POST["username"].strip(), email=request.POST["email"].strip(), password=request.POST["password"].strip()) except IntegrityError: ret["result"] = 10 except: ret["result"] = 10 user = None # this is not a good place to fire signal, but i need password for now # should create function createUser for future use if user: user.first_name = request.POST["fullname"].strip() import booki.account.signals booki.account.signals.account_created.send( sender=user, password=request.POST["password"]) try: user.save() # groups for groupName in simplejson.loads( request.POST.get("groups")): if groupName.strip() != '': sid = transaction.savepoint() try: group = BookiGroup.objects.get( url_name=groupName) group.members.add(user) except: transaction.savepoint_rollback(sid) else: transaction.savepoint_commit(sid) user2 = auth.authenticate( username=request.POST["username"].strip(), password=request.POST["password"].strip()) auth.login(request, user2) except: transaction.rollback() ret["result"] = 666 else: transaction.commit() else: transaction.rollback() if request.POST.get("method", "") == "signin": user = auth.authenticate(username=request.POST["username"].strip(), password=request.POST["password"].strip()) if user: auth.login(request, user) ret["result"] = 1 from django.core.urlresolvers import reverse ret["redirect"] = reverse('view_profile', args=[user.username]) else: try: usr = auth.models.User.objects.get( username=request.POST["username"]) # User does exist. Must be wrong password then ret["result"] = 3 except auth.models.User.DoesNotExist: # User does not exist ret["result"] = 2 try: resp = HttpResponse(simplejson.dumps(ret), mimetype="text/json") except: transaction.rollback() raise else: transaction.commit() return resp from django.core.urlresolvers import reverse redirect = request.GET.get('redirect', '') if (redirect == reverse('frontpage')): redirect = '' if request.GET.get('next', None): redirect = request.GET.get('next') joinGroups = [] for groupName in request.GET.getlist("group"): try: joinGroups.append(BookiGroup.objects.get(url_name=groupName)) except BookiGroup.DoesNotExist: pass try: resp = render_to_response( 'account/signin.html', { 'request': request, 'redirect': redirect, 'joingroups': joinGroups, 'limit_reached': limitReached }) except: transaction.rollback() raise else: transaction.commit() return resp
def forgotpassword(request): """ Django View. Gets called when user wants to change password he managed to forget. @type request: C{django.http.HttpRequest} @param request: Django Request """ from booki.utils.json_wrapper import simplejson from django.core.exceptions import ObjectDoesNotExist from django.contrib.auth.models import User if request.POST.get("ajax", "") == "1": ret = {"result": 0} usr = None if request.POST.get("method", "") == "forgot_password": def _checkIfEmpty(key): return request.POST.get(key, "").strip() == "" def _doChecksForEmpty(): if _checkIfEmpty("username"): return 2 return 0 ret["result"] = _doChecksForEmpty() if ret["result"] == 0: usersToEmail = list( User.objects.filter( Q(username=request.POST.get("username", "")) | Q(email=request.POST.get("username", "")))) for usr in usersToEmail: from booki.account import models as account_models def generateSecretCode(): import string from random import choice return ''.join([ choice(string.letters + string.digits) for i in range(30) ]) secretcode = generateSecretCode() account_models = account_models.UserPassword() account_models.user = usr account_models.remote_useragent = request.META.get( 'HTTP_USER_AGENT', '') account_models.remote_addr = request.META.get( 'REMOTE_ADDR', '') account_models.remote_host = request.META.get( 'REMOTE_HOST', '') account_models.secretcode = secretcode # In case of an error we really should not send email to user and do rest of the procedure try: account_models.save() except: transaction.rollback() else: transaction.commit() THIS_BOOKI_SERVER = config.getConfiguration( 'THIS_BOOKI_SERVER') body = render_to_string( 'account/password_reset_email.html', dict(secretcode=secretcode, hostname=THIS_BOOKI_SERVER)) from django.core.mail import EmailMessage msg = EmailMessage(_('Reset password'), body, settings.REPORT_EMAIL_USER, [usr.email]) msg.content_subtype = 'html' try: msg.send() except: ret["result"] = 4 if len(usersToEmail) == 0: ret["result"] = 3 # Do we need rollback for this?! try: resp = HttpResponse(simplejson.dumps(ret), mimetype="text/json") except: transaction.rollback() raise else: transaction.commit() return resp # Do we need commit for this?! try: resp = render_to_response('account/forgot_password.html', {"request": request}) except: transaction.rollback() raise else: transaction.commit() return resp
def create_book(request, username): """ Django View. Show content for Create Book dialog and creates book. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. """ from django.contrib.auth.models import User from booki.utils.misc import isBookLimitReached try: user = User.objects.get(username=username) except User.DoesNotExist: try: resp = pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) except: transaction.rollback() raise else: transaction.commit() return resp if isBookLimitReached() or not request.user.is_authenticated(): try: resp = pages.ErrorPage(request, "errors/no_permissions.html") except: transaction.rollback() raise else: transaction.commit() return resp from booki.utils.book import checkBookAvailability, createBook from booki.editor import models book_visible = config.getConfiguration('CREATE_BOOK_VISIBLE') book_license = config.getConfiguration('CREATE_BOOK_LICENSE') admin_create = config.getConfiguration('ADMIN_CREATE_BOOKS') if request.user.is_superuser: admin_create = False if request.GET.get("q", "") == "check": from booki.utils.json_wrapper import json data = { "available": checkBookAvailability(request.GET.get('bookname', '').strip()) } try: resp = HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() raise else: transaction.commit() return resp if request.method == 'POST' and admin_create == False: book = None try: # hidden on # description # license # title # cover book = createBook(request.user, request.POST.get('title')) lic = models.License.objects.get( abbrevation=request.POST.get('license')) book.license = lic book.description = request.POST.get('description', '') if request.POST.get("hidden", "") == "on": is_hidden = True else: is_hidden = False book.hidden = is_hidden from django.core.files import File if request.FILES.has_key('cover'): # TODO: Show some kind of error message to the user from booki.utils import misc import os try: fh, fname = misc.saveUploadedAsFile(request.FILES['cover']) book.setCover(fname) os.unlink(fname) except: pass book.save() except: transaction.rollback() else: transaction.commit() try: resp = render_to_response('account/create_book_redirect.html', { "request": request, "user": user, "book": book }) except: transaction.rollback() raise else: transaction.commit() return resp from booki.editor.models import License licenses = License.objects.all().order_by('name') try: resp = render_to_response( 'account/create_book.html', { "request": request, "book_visible": book_visible, "book_license": book_license, "admin_create": admin_create, "licenses": licenses, "user": user }) except: transaction.rollback() raise else: transaction.commit() return resp
def import_book(request, username): """ Django View. Book Import dialog. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. """ from django.contrib.auth.models import User try: user = User.objects.get(username=username) except User.DoesNotExist: try: return pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) except: transaction.rollback() finally: transaction.commit() if not request.user.is_authenticated(): try: return pages.ErrorPage(request, "errors/no_permissions.html") except: transaction.rollback() finally: transaction.commit() from booki.utils.book import checkGroupAvailability, createBookiGroup from booki.editor import models if request.GET.get("q", "") == "check": from booki.utils.json_wrapper import json data = {"available": checkGroupAvailability(request.GET.get('groupname', '').strip())} try: return HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() finally: transaction.commit() book_visible = config.getConfiguration('CREATE_BOOK_VISIBLE') admin_import = config.getConfiguration('ADMIN_IMPORT_BOOKS') if request.user.is_superuser: admin_import = False if request.GET.get("q", "") == "import" and admin_import == False: from booki.utils.json_wrapper import json data = {} try: bookid = request.GET.get('source', '') importType = request.GET.get('importtype', '') renameTitle = request.GET.get('title', '') extraOptions = {} if renameTitle: extraOptions['book_title'] = renameTitle if request.GET.get('hidden', '') != '': extraOptions['hidden'] = True importSources = { 'flossmanuals': (TWIKI_GATEWAY_URL, "en.flossmanuals.net"), "archive": (ESPRI_URL, "archive.org"), "wikibooks": (ESPRI_URL, "wikibooks"), "epub": (ESPRI_URL, "url"), } if importType == "booki": bookid = bookid.rstrip('/') booki_url, book_url_title = bookid.rsplit("/", 1) base_url = "%s/export/%s/export" % (booki_url, book_url_title) source = "booki" else: base_url, source = importSources[importType] book = common.importBookFromUrl2(user, base_url, args=dict(source=source, book=bookid), **extraOptions ) except Exception: data['imported'] = False transaction.rollback() else: transaction.commit() data['imported'] = True from django.core.urlresolvers import reverse data['info_url'] = reverse('book_info', args=[book.url_title]) try: return HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() finally: transaction.commit() try: return render_to_response('account/import_book.html', {"request": request, "book_visible": book_visible, "admin_import": admin_import, "user": user}) except: transaction.rollback() finally: transaction.commit()
def import_book(request, username): """ Django View. Book Import dialog. @type request: C{django.http.HttpRequest} @param request: Django Request @type username: C{string} @param username: Username. """ from django.contrib.auth.models import User from booki.utils.misc import isBookLimitReached try: user = User.objects.get(username=username) except User.DoesNotExist: try: resp = pages.ErrorPage(request, "errors/user_does_not_exist.html", {"username": username}) except: transaction.rollback() raise else: transaction.commit() return resp if isBookLimitReached() or not request.user.is_authenticated(): try: resp = pages.ErrorPage(request, "errors/no_permissions.html") except: transaction.rollback() raise else: transaction.commit() return resp from booki.utils.book import checkGroupAvailability, createBookiGroup from booki.editor import models if request.GET.get("q", "") == "check": from booki.utils.json_wrapper import json data = { "available": checkGroupAvailability(request.GET.get('groupname', '').strip()) } try: resp = HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() raise else: transaction.commit() return resp book_visible = config.getConfiguration('CREATE_BOOK_VISIBLE') admin_import = config.getConfiguration('ADMIN_IMPORT_BOOKS') if request.user.is_superuser: admin_import = False if request.GET.get("q", "") == "import" and admin_import == False: from booki.utils.json_wrapper import json data = {} try: bookid = request.GET.get('source', '') importType = request.GET.get('importtype', '') renameTitle = request.GET.get('title', '') extraOptions = {} if renameTitle: extraOptions['book_title'] = renameTitle if request.GET.get('hidden', '') != '': extraOptions['hidden'] = True ESPRI_URL = config.getConfiguration('ESPRI_URL') importSources = { "archive": (ESPRI_URL, "archive.org"), "wikibooks": (ESPRI_URL, "wikibooks"), "epub": (ESPRI_URL, "url"), } if importType == "booki": bookid = bookid.rstrip('/') booki_url, book_url_title = bookid.rsplit("/", 1) base_url = "%s/export/%s/export" % (booki_url, book_url_title) source = "booki" else: base_url, source = importSources[importType] book = common.importBookFromUrl2(user, base_url, args=dict(source=source, book=bookid), **extraOptions) except Exception: data['imported'] = False transaction.rollback() else: transaction.commit() data['imported'] = True from django.core.urlresolvers import reverse data['info_url'] = reverse('book_info', args=[book.url_title]) try: resp = HttpResponse(json.dumps(data), "text/plain") except: transaction.rollback() raise else: transaction.commit() return resp try: resp = render_to_response( 'account/import_book.html', { "request": request, "book_visible": book_visible, "admin_import": admin_import, "user": user }) except: transaction.rollback() raise else: transaction.commit() return resp
def importFeed(document, conf): """ Imports content of Wordpress export into Booktype. """ # To create a book we use "createBook" function. It will do good part of magic for us in the background. # We have to provide: # - owner of the book; every book must have an owner # - book title; this is full book name # - book status; every book has a status, let us just use "new" for now # - book url; book must have unique name and in Booktype world it is book url name from booki.utils.book import createBook book = createBook(conf['user'], conf['bookTitle'], status="new", bookURL=conf['bookTitleURL']) # We use config API to check if books are by default visible or not isVisible = config.getConfiguration('CREATE_BOOK_VISIBLE', True) book.hidden = not isVisible book.save() # "createBook" function has already created default list of statuses. Let's just fetch "new" status because # we will need it for Chapters later stat = models.BookStatus.objects.filter(book=book, name="new")[0] # What is default URL for Wordpress blog wpLink = document['feed']['link'] attachments = [] for item in document['items']: # We only care about posts which have "publish" status. Ignore everything else for now. if item['wp_status'] != u'publish': continue chapterTitle = item['title'] print '>> ', chapterTitle # So... let's clean our Wordpress post a bit. Here we ASSUME that empty line is used to separate paragraphs in Wordpress post. content = item['content'][0]['value'].replace('\r\n', '\n') content = '\n'.join([ '<p>%s</p>' % p for p in content.split('\n\n') if p.strip() != '' ]) # Every Booktype chapter starts with Chapter title embded in H2 tag. content = u'<h2>%s</h2>%s' % (chapterTitle, content) tree = html.document_fromstring(content) for e in tree.iter(): # We only care about images now if e.tag == 'img': src = e.get('src') if src: if src.startswith('/'): src = wpLink + src # We don't need to download picture if it was already downloaed if not src in attachments: attachments.append(src) u = urlparse.urlsplit(src) # Get the file name and take care of funny stuff like %20 in file names fileName = os.path.basename(urllib.unquote(u.path)) print ' >> ', fileName # Download image data = downloadFile(src) # Let us create this attachment if we managed to download something if data: # Create new Attachment. "book" argument is part of legacy here, we really should care only about "version". # Expect this to be removed in the future. Also, every Attachment can have different status. Not that it is # used anywhere at the moment, but it has to be here. att = models.Attachment(book=book, version=book.version, status=stat) # We use standard method for saving the data. f2 = File(StringIO(data)) f2.size = len(data) att.attachment.save(fileName, f2, save=True) # If filename with the same name already exists then Django will add prefix to the name. # For instance: Image.jpg would become Image_1.jpg. That is why we check the new name. fileName = os.path.basename(att.attachment.path) # Set whatever we got as a new attachment name. Also notice all images are referenced as # "static/image.jpg" in Booktype so we have to change the source also. e.set('src', 'static/%s' % fileName) content = etree.tostring(tree, encoding='UTF-8', method='html') # Create new chapter. New chapter will be in "Hold chapters". If you want it to be in "Table of contents" you would # need to do some extra magic. But we don't care about it now. We also don't really care about writing anything to # log files... now = datetime.datetime.now() chapter = models.Chapter(book=book, version=book.version, url_title=bookiSlugify(chapterTitle), title=chapterTitle, status=stat, content=content, created=now, modified=now) chapter.save()