merge player changes and detail page + search
authorMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Thu, 29 Dec 2011 16:17:54 +0000 (17:17 +0100)
committerMarcin Koziej <marcin.koziej@nowoczesnapolska.org.pl>
Thu, 29 Dec 2011 16:17:54 +0000 (17:17 +0100)
Conflicts:
wolnelektury/static/css/base.css
wolnelektury/static/css/book_box.css
wolnelektury/templates/catalogue/book_short.html

1  2 
apps/catalogue/models.py
apps/catalogue/urls.py
wolnelektury/settings.py
wolnelektury/static/css/base.css
wolnelektury/static/css/book_box.css
wolnelektury/static/css/header.css
wolnelektury/templates/catalogue/book_short.html
wolnelektury/urls.py

diff --combined apps/catalogue/models.py
@@@ -24,15 -24,13 +24,15 @@@ from newtagging.models import TagBase, 
  from newtagging import managers
  from catalogue.fields import JSONField, OverwritingFileField
  from catalogue.utils import create_zip, split_tags
 -from catalogue.tasks import touch_tag
 +from catalogue.tasks import touch_tag, index_book
  from shutil import copy
  from glob import glob
  import re
  from os import path
  
  
 +import search
 +
  TAG_CATEGORIES = (
      ('author', _('author')),
      ('epoch', _('epoch')),
@@@ -510,12 -508,16 +510,12 @@@ class Book(models.Model)
              tags = self.tags.filter(category__in=('author', 'kind', 'genre', 'epoch'))
              tags = split_tags(tags)
  
 -            formats = []
 +            formats = {}
              # files generated during publication
              for ebook_format in self.ebook_formats:
                  if self.has_media(ebook_format):
 -                    formats.append(u'<a href="%s">%s</a>' % (
 -                        self.get_media(ebook_format).url,
 -                        ebook_format.upper()
 -                    ))
 +                    formats[ebook_format] = self.get_media(ebook_format)
  
 -            formats = [mark_safe(format) for format in formats]
  
              short_html = unicode(render_to_string('catalogue/book_short.html',
                  {'book': self, 'tags': tags, 'formats': formats}))
                      getattr(settings, "ALL_%s_ZIP" % format_.upper()))
          return result.wait()
  
-     def zip_audiobooks(self):
-         bm = BookMedia.objects.filter(book=self, type='mp3')
+     def zip_audiobooks(self, format_):
+         bm = BookMedia.objects.filter(book=self, type=format_)
          paths = map(lambda bm: (None, bm.file.path), bm)
-         result = create_zip.delay(paths, self.fileid())
+         result = create_zip.delay(paths, "%s_%s" % (self.fileid(), format_))
          return result.wait()
  
 +    def search_index(self, book_info=None):
 +        if settings.CELERY_ALWAYS_EAGER:
 +            idx = search.ReusableIndex()
 +        else:
 +            idx = search.Index()
 +            
 +        idx.open()
 +        try:
 +            idx.index_book(self, book_info)
 +            idx.index_tags()
 +        finally:
 +            idx.close()
 +
      @classmethod
      def from_xml_file(cls, xml_file, **kwargs):
          from django.core.files import File
  
      @classmethod
      def from_text_and_meta(cls, raw_file, book_info, overwrite=False,
 -            build_epub=True, build_txt=True, build_pdf=True, build_mobi=True):
 +            build_epub=True, build_txt=True, build_pdf=True, build_mobi=True,
 +            search_index=True):
          import re
          from sortify import sortify
  
          if not settings.NO_BUILD_MOBI and build_mobi:
              book.build_mobi()
  
 +        if not settings.NO_SEARCH_INDEX and search_index:
 +            index_book.delay(book.id, book_info)
 +
          book_descendants = list(book.children.all())
          descendants_tags = set()
          # add l-tag to descendants and their fragments
@@@ -1031,7 -1016,7 +1031,7 @@@ class Fragment(models.Model)
          verbose_name_plural = _('fragments')
  
      def get_absolute_url(self):
 -        return '%s#m%s' % (self.book.get_html_url(), self.anchor)
 +        return '%s#m%s' % (reverse('book_text', args=[self.book.slug]), self.anchor)
  
      def reset_short_html(self):
          if self.id is None:
diff --combined apps/catalogue/urls.py
@@@ -26,16 -26,18 +26,18 @@@ urlpatterns = patterns('picture.views'
      url(r'^polki/nowa/$', 'new_set', name='new_set'),
      url(r'^tags/$', 'tags_starting_with', name='hint'),
      url(r'^jtags/$', 'json_tags_starting_with', name='jhint'),
 -    url(r'^szukaj/$', 'search', name='search'),
 +    url(r'^szukaj/$', 'search', name='old_search'),
  
      # zip
-     #url(r'^zip/pdf\.zip$', 'download_zip', {'format': 'pdf', 'slug': None}, 'download_zip_pdf'),
-     #url(r'^zip/epub\.zip$', 'download_zip', {'format': 'epub', 'slug': None}, 'download_zip_epub'),
-     #url(r'^zip/mobi\.zip$', 'download_zip', {'format': 'mobi', 'slug': None}, 'download_zip_mobi'),
-     #url(r'^zip/audiobook/(?P<book>%s)\.zip' % Book.FILEID_RE, 'download_zip', {'format': 'audiobook'}, 'download_zip_audiobook'),
+     url(r'^zip/pdf\.zip$', 'download_zip', {'format': 'pdf', 'slug': None}, 'download_zip_pdf'),
+     url(r'^zip/epub\.zip$', 'download_zip', {'format': 'epub', 'slug': None}, 'download_zip_epub'),
+     url(r'^zip/mobi\.zip$', 'download_zip', {'format': 'mobi', 'slug': None}, 'download_zip_mobi'),
+     url(r'^zip/mp3/(?P<book>%s)\.zip' % Book.FILEID_RE, 'download_zip', {'format': 'mp3'}, 'download_zip_mp3'),
+     url(r'^zip/ogg/(?P<book>%s)\.zip' % Book.FILEID_RE, 'download_zip', {'format': 'ogg'}, 'download_zip_ogg'),
  
      # Public interface. Do not change this URLs.
      url(r'^lektura/(?P<book>%s)\.html$' % Book.FILEID_RE, 'book_text', name='book_text'),
+     url(r'^lektura/(?P<book>%s)/audiobook/$' % Book.URLID_RE, 'player', name='book_player'),
      url(r'^lektura/(?P<book>%s)/$' % Book.URLID_RE, 'book_detail', name='book_detail'),
      url(r'^lektura/(?P<book>%s)/motyw/(?P<theme_slug>[a-zA-Z0-9-]+)/$' % Book.URLID_RE,
          'book_fragments', name='book_fragments'),
diff --combined wolnelektury/settings.py
@@@ -60,7 -60,6 +60,7 @@@ USE_I18N = Tru
  # Example: "/home/media/media.lawrence.com/"
  MEDIA_ROOT = path.join(PROJECT_DIR, '../media')
  STATIC_ROOT = path.join(PROJECT_DIR, 'static')
 +SEARCH_INDEX = path.join(MEDIA_ROOT, 'search')
  
  # URL that handles the media served from MEDIA_ROOT. Make sure to use a
  # trailing slash if there is a path component (optional in other cases).
@@@ -154,7 -153,6 +154,7 @@@ INSTALLED_APPS = 
      'stats',
      'suggest',
      'picture',
 +    'search',
  ]
  
  #CACHE_BACKEND = 'locmem:///?max_entries=3000'
@@@ -176,8 -174,6 +176,8 @@@ COMPRESS_CSS = 
              'css/book_box.css',
              'css/catalogue.css',
              'css/sponsors.css',
 +            
 +            'css/ui-lightness/jquery-ui-1.8.16.custom.css',
          ],
          'output_filename': 'css/all.min?.css',
      },
          'source_filenames': ('css/master.book.css',),
          'output_filename': 'css/book.min?.css',
      },
+     'player': {
+         'source_filenames': [
+             'jplayer/jplayer.blue.monday.css', 
+         ],
+         'output_filename': 'css/player.min?.css',
+     },
      'simple': {
          'source_filenames': ('css/simple.css',),
          'output_filename': 'css/simple.min?.css',
@@@ -202,21 -204,25 +208,29 @@@ COMPRESS_JS = 
              'js/jquery.countdown-es.js', 'js/jquery.countdown-lt.js',
              'js/jquery.countdown-ru.js', 'js/jquery.countdown-fr.js',
  
 +            'js/jquery-ui-1.8.16.custom.min.js',
 +
              'js/locale.js',
              'js/dialogs.js',
              'js/sponsors.js',
              'js/base.js',
              'js/pdcounter.js',
  
 +            'js/search.js',
 +
              #~ 'js/jquery.autocomplete.js',
              #~ 'js/jquery.labelify.js', 'js/catalogue.js',
              ),
          'output_filename': 'js/base?.min.js',
      },
+     'player': {
+         'source_filenames': [
+             'jplayer/jquery.jplayer.min.js', 
+             'jplayer/jplayer.playlist.min.js', 
+             'js/player.js', 
+         ],
+         'output_filename': 'js/player.min?.js',
+     },
      #~ 'book': {
          #~ 'source_filenames': ('js/jquery.eventdelegation.js', 'js/jquery.scrollto.js', 'js/jquery.highlightfade.js', 'js/book.js',),
          #~ 'source_filenames': [],
@@@ -258,15 -264,14 +272,16 @@@ MAX_TAG_LIST = 
  NO_BUILD_EPUB = False
  NO_BUILD_TXT = False
  NO_BUILD_PDF = False
 -NO_BUILD_MOBI = False
 +NO_BUILD_MOBI = True
 +NO_SEARCH_INDEX = False
 +SEARCH_INDEX_PARALLEL = False
  
  ALL_EPUB_ZIP = 'wolnelektury_pl_epub'
  ALL_PDF_ZIP = 'wolnelektury_pl_pdf'
  ALL_MOBI_ZIP = 'wolnelektury_pl_mobi'
  
  CATALOGUE_DEFAULT_LANGUAGE = 'pol'
+ PUBLISH_PLAN_FEED = 'http://redakcja.wolnelektury.pl/documents/track/editor-proofreading/'
  
  PAGINATION_INVALID_PAGE_RAISES_404 = True
  
@@@ -281,7 -286,6 +296,7 @@@ BROKER_PASSWORD = "guest
  BROKER_VHOST = "/"
  
  
 +
  # Load localsettings, if they exist
  try:
      from localsettings import *
@@@ -69,11 -69,9 +69,11 @@@ h2 
  .page-desc {
      margin-left: 1.5em;
  }
 +
  .inline-tag-lists {
      font-size: 1.1em;
  }
 +
  #themes-list-toggle:after {
      padding-left: 1em;
      content: "↓";
@@@ -92,7 -90,7 +92,7 @@@
      -moz-box-shadow: 2px 2px 2px #ddd;
      -webkit-box-shadow: 2px 2px 2px #ddd;
      box-shadow: 2px 2px 2px #ddd;
-     z-index: 2;
+     z-index: 500;
  }
  #themes-list ul {
      list-style: none;
@@@ -1,4 -1,4 +1,4 @@@
 -.book-mini-box, .book-box {
 +.book-wide-box, .book-mini-box, .book-box {
      display: inline-block;
      margin: 0;
      vertical-align: top;
      width: 16.15em;
  }
  
 +.book-wide-box {
 +    width: 98.5em;
 +}
 +
  .book-mini-box a, .book-box-inner {
      display: block;
      color: black;
      margin: .5em;
  }
  
 -.book-mini-box img, .book-box img {
 +.book-mini-box img, .book-box img, .book-wide-box img {
      width: 13.9em;
      height: 19.3em;
  }
  .book-mini-box img {
      margin-bottom: 1.8em;
  }
 -.book-box img {
 +.book-box img, .book-wide-box img {
      float: left;
      margin-right: 1.5em;
  }
  .book-box-download {
      position: relative;
  }
 +
 +.book-box-download a {
 +    position: relative;
 +    z-index: 1;
 +}
 +
  .book-box-formats {
      display: none;
      position: absolute;
  
 +    width: 16.363em;
      border: 1px solid #ddd;
 -    padding: .8em 1em;
 +    padding: 3.454em 1.727em .818em 1.727em;
      background: #fff;
      -moz-box-shadow: 2px 2px 2px #ddd;
      -webkit-box-shadow: 2px 2px 2px #ddd;
      box-shadow: 2px 2px 2px #ddd;
 -    
 +
 +    z-index: 0;
 +    top: -1.454em;
 +    left: -1.727em;
  }
 -.book-box-formats a {
 +.book-box-formats span {
      display: block;
  }
 + 
 +
 +.book-box-download:hover .book-box-formats:first {
 +    margin-top: 1.454em;
 +}
 +
  .book-box-download:hover .book-box-formats {
      display: block;
  }
  .book-box-tools {
      font-size: 1.1em;
  }
 -.book-box-read a:before {
++
 +.book-box-tools a.downarrow:before {
-     content: "⇩";
+     content: "\2609";
+     font-family: WL-Nav;
+     font-size: 2.25em;
+     margin-right: .15em;
+     vertical-align: middle;
+ }
 -.book-box-download a:before {
 -    content: "⇩";
 -    font-family: WL-Nav;
 -    font-size: 2.25em;
 -    margin-right: .15em;
 -    vertical-align: middle;
 -}
++
+ .book-box-audiobook a:before {
+     content: "\266B";
      font-family: WL-Nav;
-     font-size: 2em;
-     margin-right: .25em;
+     font-size: 2.25em;
+     margin-right: .15em;
      vertical-align: middle;
  }
 +
 +ul.book-box-tools {
 +    margin: 0;
 +    padding: 0;
 +}
 +
 +.book-box-tools li {
 +    display: inline-block;
 +}
 +
  .book-box-read {
-     width: 11em;
+     width: 11.5em;
  }
  .book-box-download {
-     width: 8em;
+     width: 8.5em;
  }
  .book-box-audiobook {
-     width: 8em;
+     width: 7em;
  }
 +
 +.book-wide-box .right-column {
 +    float: right;
 +    width: 41.5em;
 +}
 +
 +.book-wide-box blockquote.cite-body {
 +    /* @ 18pt */
 +    width: 100%; /*23.055em;*/
 +    height: 7.222em;
 +    background-color: #f7f7f7;
 +    margin: 0;
 +    position: relative;
 +    top: -0.444em;
 +    right: -0.555em;
 +    vertical-align: center;
 +}
 +
 +.book-wide-box blockquote div {
 +    padding: 0.888em;
 +}
 +
 +.book-wide-box #other-tools {
 +    float: left;
 +    width: 14.5em;
 +    margin-left: 1.5em;
 +    
 +}
 +
 +
 +.book-wide-box #other-download {
 +    float: left;
 +    width 22.5em;
 +    margin: 0em 1.5em 0em 1.5em
 +}
@@@ -38,7 -38,7 +38,7 @@@
  #logo {
      position: absolute;
      top: 1.9em;
 -    margin-left: 1.6em;
 +    margin-left: 1.5em;
  }
  
  #logo a {
@@@ -49,7 -49,7 +49,7 @@@
  
  #tagline {
      display: inline-block;
 -    margin-left: 24em;
 +    margin-left: 25.5em;
  }
  #tagline span {
      font-size: 1.1em;
@@@ -66,8 -66,8 +66,8 @@@
      display: inline-block;
      width: 63.1em;
      padding-left: .5em;
-     padding-right: .5em;
-     padding-top: 0;
+     padding-right: 0;
+     padding-top: 0.5em;
      padding-bottom: 0;
  }
  
@@@ -92,6 -92,7 +92,7 @@@
      padding: 0;
      margin: 0;
      width: 9.4em;
+     float: right;
  }
  #search-button button {
      font-size: 1em;
@@@ -1,6 -1,6 +1,6 @@@
  {% load i18n %}
  {% load thumbnail %}
 -<div class="book-box">
 +<div class="{% block box-class %}book-box{% endblock %}">
  <div class="book-box-inner">
      <a href="{{ book.get_absolute_url }}">
          {% if book.cover %}
@@@ -13,8 -13,6 +13,8 @@@
              " alt="Cover" />
          {% endif %}
      </a>
 +    {% block right-column %}
 +    {% endblock %}
      <div class="book-box-body">
          <div class="book-box-head">
              <div class="mono author">
      <ul class="book-box-tools">
          <li class="book-box-read">
          {% if book.html_file %}
 -            <a href="{% url book_text book.urlid %}" class="mono">{% trans "Read online" %}</a>
 +            <a href="{% url book_text book.urlid %}" class="mono downarrow">{% trans "Read online" %}</a>
          {% endif %}
          </li>
          <li class="book-box-download">
 -            <a class="mono">{% trans "Download" %}</a>
 +            <a class="mono downarrow">{% trans "Download" %}</a>
              <div class="book-box-formats mono">
 -                {{ formats|join:"" }}
 +            {% if formats.pdf %}
 +            <span><a href="{{formats.pdf.url}}">PDF</a> do wydruku</span>
 +            {% endif %}
 +            {% if formats.epub %}
 +            <span><a href="{{formats.epub.url}}">EPUB</a> na czytnik</span>
 +            {% endif %}
 +            {% if formats.mobi %}
 +            <span><a href="{{formats.mobi.url}}">MOBI</a> na Kindle</span>
 +            {% endif %}
 +            {% if formats.txt %}
 +            <span><a href="{{formats.txt.url}}">TXT</a> do zadań specjalnych</span>
 +            {% endif %}
              </div>
          </li>
          <li class="book-box-audiobook">
          {% if book.has_mp3_file %}
-             <a href="" class="mono downarrow">{% trans "Audiobook" %}</a>
 -            <a href="{% url book_player book.slug %}" class="open-player mono">{% trans "Listen" %}</a>
++            <a href="{% url book_player book.slug %}" class="open-player mono downarrow">{% trans "Listen" %}</a>
          {% endif %}
          </li>
      </ul>
 +    {% block box-append %}
 +    {% endblock %}
  </div>
  </div>
diff --combined wolnelektury/urls.py
@@@ -11,6 -11,7 +11,7 @@@ admin.autodiscover(
  
  urlpatterns = patterns('wolnelektury.views',
      url(r'^$', 'main_page', name='main_page'),
+     url(r'^planowane/$', 'publish_plan', name='publish_plan'),
  
      url(r'^zegar/$', 'clock', name='clock'),
  
@@@ -39,8 -40,6 +40,8 @@@ urlpatterns += patterns(''
      # API
      (r'^api/', include('api.urls')),
  
 +    url(r'^fullsearch/', include('search.urls')),
 +
      # Static files
      url(r'^%s(?P<path>.*)$' % settings.MEDIA_URL[1:], 'django.views.static.serve',
          {'document_root': settings.MEDIA_ROOT, 'show_indexes': True}),