├── .gitignore ├── .gitinit ├── Procfile ├── README.md ├── data.sql ├── doc ├── Makefile ├── _build │ ├── doctrees │ │ ├── environment.pickle │ │ └── index.doctree │ └── latex │ │ ├── Makefile │ │ ├── fncychap.sty │ │ ├── onlinelibrarymanagementsystem.aux │ │ ├── onlinelibrarymanagementsystem.idx │ │ ├── onlinelibrarymanagementsystem.out │ │ ├── onlinelibrarymanagementsystem.pdf │ │ ├── onlinelibrarymanagementsystem.tex │ │ ├── onlinelibrarymanagementsystem.toc │ │ ├── python.ist │ │ ├── sphinx.sty │ │ ├── sphinxhowto.cls │ │ ├── sphinxmanual.cls │ │ └── tabulary.sty ├── conf.py └── index.txt ├── library ├── __init__.py ├── settings.py ├── templates │ ├── about.html │ ├── author_show.html │ ├── authors.html │ ├── base.html │ ├── book_show.html │ ├── books.html │ ├── change_password.html │ ├── home.html │ ├── my_quotations.html │ ├── new.html │ ├── period_show.html │ ├── periods.html │ ├── public_home.html │ ├── publisher_show.html │ ├── publishers.html │ ├── search_users.html │ ├── sign_in.html │ ├── sign_up.html │ ├── table_without_footer.html │ ├── user.html │ └── useredit.html ├── urls.py └── wsgi.py ├── library_app ├── __init__.py ├── admin.py ├── auth_backend.py ├── context_processor.py ├── decorators │ ├── __init__.py │ └── group_required.py ├── fixtures │ └── users.json ├── forms.py ├── helpers.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20141218_1051.py │ ├── 0003_auto_20141218_1200.py │ ├── 0004_quotationfrombook.py │ ├── 0005_auto_20141229_1907.py │ └── __init__.py ├── models.py ├── static │ ├── css │ │ ├── bootstrap-responsive.css │ │ ├── bootstrap-responsive.min.css │ │ ├── bootstrap.css │ │ ├── bootstrap.min.css │ │ ├── public_home.less │ │ └── style.less │ ├── img │ │ ├── blank-face.jpg │ │ ├── c1.jpg │ │ ├── c2.jpg │ │ ├── c2_cover.jpg │ │ ├── c2_web_banner.jpg │ │ ├── c3.jpg │ │ ├── c3_cover.jpg │ │ ├── code.jpg │ │ ├── cover.jpg │ │ ├── face.jpg │ │ ├── female-placeholder.png │ │ ├── flower.png │ │ ├── glyphicons-halflings-white.png │ │ ├── glyphicons-halflings.png │ │ ├── logo.png │ │ ├── logo_big.png │ │ ├── logo_small.png │ │ ├── palm.jpg │ │ └── road.jpg │ └── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── less.js │ │ ├── main.js │ │ └── public_home.js ├── tables.py ├── templatetags │ ├── __init__.py │ ├── has_group.py │ ├── render_object.py │ └── xextends.py ├── tests.py ├── validators.py └── views.py ├── manage.py └── requirements.txt /.gitignore: -------------------------------------------------------------------------------- 1 | sqlite3.db 2 | *.db 3 | *.py[cod] 4 | *.log -------------------------------------------------------------------------------- /.gitinit: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: gunicorn library.wsgi 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Library Online Management System written in Django 2 | --- 3 | 4 | ####Link: http://django-library.herokuapp.com/ 5 | 6 | **Technologies**: django, python, html, css, less, Java Script, jQuery, Twitter Bootstrap, Git, Heroku, Selenium, 7 | django_tables2, fandjango, Google App Engine (by CodeShip) 8 | 9 | **Date**: December, 2014 10 | 11 | >It is an online interface for a library (with a few social-network features) and allows users to: 12 | - borrow/return books (like in real library) (a few real books are present in the system) 13 | - create circles of friends (like in google+ or facebook) (add to friends and unfriend) 14 | - share with friends books' quotation (in twitter style), borrowed books 15 | - register/sign in via facebook and webpage 16 | - save quotations from books 17 | 18 | >There is also group of librarians with additional permissions: 19 | - custom (outside of django admin) CRUD for authors, books' publishers, books etc. 20 | - librarian can mark that book has been returned to library 21 | 22 | Front-end is designed using Twitter Bootstrap and filled out with 23 | sample data (mostly lorem ipsum). A few animations/effects are programmed using jQuery. 24 | 25 | For facebook integration I used facepy and fandjango. 26 | 27 | Application is provided with test (basic ones, unittests and selenium). 28 | 29 | Data validations is done using (mostly) modelForms. 30 | 31 | Books/Authors/Publishers/Users search is made using django_tables2. It allows user to sort results 32 | using selected criteria, watch selected amount of entries on page (pagination) etc. I have used user's images 33 | generated by gravator. 34 | 35 | **Exemplary system accounts**: 36 | 37 | librarian account: 38 | - login: assistant 39 | - pass: 12345 40 | - (do not worry, I have database backup ;)) 41 | 42 | standard user 43 | - login: user1 44 | - pass: 12345 45 | 46 | I intended to document every fragment of code that could be unclear. Enclosed is documentation 47 | created by sphinx. 48 | 49 | **Run**: 50 | ```sh 51 | python manage.py runserver 127.0.0.1:8888 52 | ``` 53 | 54 | (do not forget to change database settings if you want to run app locally) or simply **visit website: 55 | http://django-library.herokuapp.com/** 56 | 57 | **Author: Tomasz Potanski, tomasz@potanski.pl** 58 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # User-friendly check for sphinx-build 11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) 12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) 13 | endif 14 | 15 | # Internal variables. 16 | PAPEROPT_a4 = -D latex_paper_size=a4 17 | PAPEROPT_letter = -D latex_paper_size=letter 18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 19 | # the i18n builder cannot share the environment and doctrees with the others 20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 21 | 22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 23 | 24 | help: 25 | @echo "Please use \`make ' where is one of" 26 | @echo " html to make standalone HTML files" 27 | @echo " dirhtml to make HTML files named index.html in directories" 28 | @echo " singlehtml to make a single large HTML file" 29 | @echo " pickle to make pickle files" 30 | @echo " json to make JSON files" 31 | @echo " htmlhelp to make HTML files and a HTML help project" 32 | @echo " qthelp to make HTML files and a qthelp project" 33 | @echo " devhelp to make HTML files and a Devhelp project" 34 | @echo " epub to make an epub" 35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 36 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 38 | @echo " text to make text files" 39 | @echo " man to make manual pages" 40 | @echo " texinfo to make Texinfo files" 41 | @echo " info to make Texinfo files and run them through makeinfo" 42 | @echo " gettext to make PO message catalogs" 43 | @echo " changes to make an overview of all changed/added/deprecated items" 44 | @echo " xml to make Docutils-native XML files" 45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 46 | @echo " linkcheck to check all external links for integrity" 47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 48 | 49 | clean: 50 | rm -rf $(BUILDDIR)/* 51 | 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | dirhtml: 58 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 59 | @echo 60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 61 | 62 | singlehtml: 63 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 64 | @echo 65 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 66 | 67 | pickle: 68 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 69 | @echo 70 | @echo "Build finished; now you can process the pickle files." 71 | 72 | json: 73 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 74 | @echo 75 | @echo "Build finished; now you can process the JSON files." 76 | 77 | htmlhelp: 78 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 79 | @echo 80 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 81 | ".hhp project file in $(BUILDDIR)/htmlhelp." 82 | 83 | qthelp: 84 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 85 | @echo 86 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 87 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 88 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/onlinelibrarymanagementsystem.qhcp" 89 | @echo "To view the help file:" 90 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/onlinelibrarymanagementsystem.qhc" 91 | 92 | devhelp: 93 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 94 | @echo 95 | @echo "Build finished." 96 | @echo "To view the help file:" 97 | @echo "# mkdir -p $$HOME/.local/share/devhelp/onlinelibrarymanagementsystem" 98 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/onlinelibrarymanagementsystem" 99 | @echo "# devhelp" 100 | 101 | epub: 102 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 103 | @echo 104 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 105 | 106 | latex: 107 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 108 | @echo 109 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 110 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 111 | "(use \`make latexpdf' here to do that automatically)." 112 | 113 | latexpdf: 114 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 115 | @echo "Running LaTeX files through pdflatex..." 116 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 117 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 118 | 119 | latexpdfja: 120 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 121 | @echo "Running LaTeX files through platex and dvipdfmx..." 122 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 123 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 124 | 125 | text: 126 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 127 | @echo 128 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 129 | 130 | man: 131 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 132 | @echo 133 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 134 | 135 | texinfo: 136 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 137 | @echo 138 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 139 | @echo "Run \`make' in that directory to run these through makeinfo" \ 140 | "(use \`make info' here to do that automatically)." 141 | 142 | info: 143 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 144 | @echo "Running Texinfo files through makeinfo..." 145 | make -C $(BUILDDIR)/texinfo info 146 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 147 | 148 | gettext: 149 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 150 | @echo 151 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 152 | 153 | changes: 154 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 155 | @echo 156 | @echo "The overview file is in $(BUILDDIR)/changes." 157 | 158 | linkcheck: 159 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 160 | @echo 161 | @echo "Link check complete; look for any errors in the above output " \ 162 | "or in $(BUILDDIR)/linkcheck/output.txt." 163 | 164 | doctest: 165 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 166 | @echo "Testing of doctests in the sources finished, look at the " \ 167 | "results in $(BUILDDIR)/doctest/output.txt." 168 | 169 | xml: 170 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 171 | @echo 172 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 173 | 174 | pseudoxml: 175 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 176 | @echo 177 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 178 | -------------------------------------------------------------------------------- /doc/_build/doctrees/environment.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/doc/_build/doctrees/environment.pickle -------------------------------------------------------------------------------- /doc/_build/doctrees/index.doctree: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/doc/_build/doctrees/index.doctree -------------------------------------------------------------------------------- /doc/_build/latex/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx LaTeX output 2 | 3 | ALLDOCS = $(basename $(wildcard *.tex)) 4 | ALLPDF = $(addsuffix .pdf,$(ALLDOCS)) 5 | ALLDVI = $(addsuffix .dvi,$(ALLDOCS)) 6 | 7 | # Prefix for archive names 8 | ARCHIVEPRREFIX = 9 | # Additional LaTeX options 10 | LATEXOPTS = 11 | 12 | all: $(ALLPDF) 13 | all-pdf: $(ALLPDF) 14 | all-dvi: $(ALLDVI) 15 | all-ps: all-dvi 16 | for f in *.dvi; do dvips $$f; done 17 | 18 | all-pdf-ja: 19 | for f in *.pdf *.png *.gif *.jpg *.jpeg; do extractbb $$f; done 20 | for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done 21 | for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done 22 | for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done 23 | -for f in *.idx; do mendex -U -f -d "`basename $$f .idx`.dic" -s python.ist $$f; done 24 | for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done 25 | for f in *.tex; do platex -kanji=utf8 $(LATEXOPTS) $$f; done 26 | for f in *.dvi; do dvipdfmx $$f; done 27 | 28 | zip: all-$(FMT) 29 | mkdir $(ARCHIVEPREFIX)docs-$(FMT) 30 | cp $(ALLPDF) $(ARCHIVEPREFIX)docs-$(FMT) 31 | zip -q -r -9 $(ARCHIVEPREFIX)docs-$(FMT).zip $(ARCHIVEPREFIX)docs-$(FMT) 32 | rm -r $(ARCHIVEPREFIX)docs-$(FMT) 33 | 34 | tar: all-$(FMT) 35 | mkdir $(ARCHIVEPREFIX)docs-$(FMT) 36 | cp $(ALLPDF) $(ARCHIVEPREFIX)docs-$(FMT) 37 | tar cf $(ARCHIVEPREFIX)docs-$(FMT).tar $(ARCHIVEPREFIX)docs-$(FMT) 38 | rm -r $(ARCHIVEPREFIX)docs-$(FMT) 39 | 40 | bz2: tar 41 | bzip2 -9 -k $(ARCHIVEPREFIX)docs-$(FMT).tar 42 | 43 | # The number of LaTeX runs is quite conservative, but I don't expect it 44 | # to get run often, so the little extra time won't hurt. 45 | %.dvi: %.tex 46 | latex $(LATEXOPTS) '$<' 47 | latex $(LATEXOPTS) '$<' 48 | latex $(LATEXOPTS) '$<' 49 | -makeindex -s python.ist '$(basename $<).idx' 50 | latex $(LATEXOPTS) '$<' 51 | latex $(LATEXOPTS) '$<' 52 | 53 | %.pdf: %.tex 54 | pdflatex $(LATEXOPTS) '$<' 55 | pdflatex $(LATEXOPTS) '$<' 56 | pdflatex $(LATEXOPTS) '$<' 57 | -makeindex -s python.ist '$(basename $<).idx' 58 | pdflatex $(LATEXOPTS) '$<' 59 | pdflatex $(LATEXOPTS) '$<' 60 | 61 | clean: 62 | rm -f *.dvi *.log *.ind *.aux *.toc *.syn *.idx *.out *.ilg *.pla 63 | 64 | .PHONY: all all-pdf all-dvi all-ps clean 65 | .PHONY: all-pdf-ja 66 | 67 | -------------------------------------------------------------------------------- /doc/_build/latex/onlinelibrarymanagementsystem.aux: -------------------------------------------------------------------------------- 1 | \relax 2 | \providecommand\hyper@newdestlabel[2]{} 3 | \providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} 4 | \HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined 5 | \global\let\oldcontentsline\contentsline 6 | \gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}} 7 | \global\let\oldnewlabel\newlabel 8 | \gdef\newlabel#1#2{\newlabelxx{#1}#2} 9 | \gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} 10 | \AtEndDocument{\ifx\hyper@anchor\@undefined 11 | \let\contentsline\oldcontentsline 12 | \let\newlabel\oldnewlabel 13 | \fi} 14 | \fi} 15 | \global\let\hyper@last\relax 16 | \gdef\HyperFirstAtBeginDocument#1{#1} 17 | \providecommand\HyField@AuxAddToFields[1]{} 18 | \providecommand\HyField@AuxAddToCoFields[2]{} 19 | \select@language{english} 20 | \@writefile{toc}{\select@language{english}} 21 | \@writefile{lof}{\select@language{english}} 22 | \@writefile{lot}{\select@language{english}} 23 | \newlabel{index::doc}{{}{1}{}{section*.2}{}} 24 | \@writefile{toc}{\contentsline {chapter}{\numberline {1}Indices and tables}{3}{chapter.1}} 25 | \@writefile{lof}{\addvspace {10\p@ }} 26 | \@writefile{lot}{\addvspace {10\p@ }} 27 | \newlabel{index:indices-and-tables}{{1}{3}{Indices and tables}{chapter.1}{}} 28 | \newlabel{index:welcome-to-online-library-management-system-s-documentation}{{1}{3}{Indices and tables}{chapter.1}{}} 29 | -------------------------------------------------------------------------------- /doc/_build/latex/onlinelibrarymanagementsystem.idx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/doc/_build/latex/onlinelibrarymanagementsystem.idx -------------------------------------------------------------------------------- /doc/_build/latex/onlinelibrarymanagementsystem.out: -------------------------------------------------------------------------------- 1 | \BOOKMARK [0][-]{chapter.1}{Indices and tables}{}% 1 2 | -------------------------------------------------------------------------------- /doc/_build/latex/onlinelibrarymanagementsystem.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/doc/_build/latex/onlinelibrarymanagementsystem.pdf -------------------------------------------------------------------------------- /doc/_build/latex/onlinelibrarymanagementsystem.tex: -------------------------------------------------------------------------------- 1 | % Generated by Sphinx. 2 | \def\sphinxdocclass{report} 3 | \documentclass[letterpaper,10pt,english]{sphinxmanual} 4 | \usepackage[utf8]{inputenc} 5 | \DeclareUnicodeCharacter{00A0}{\nobreakspace} 6 | \usepackage{cmap} 7 | \usepackage[T1]{fontenc} 8 | \usepackage{babel} 9 | \usepackage{times} 10 | \usepackage[Bjarne]{fncychap} 11 | \usepackage{longtable} 12 | \usepackage{sphinx} 13 | \usepackage{multirow} 14 | 15 | 16 | \title{online library management system Documentation} 17 | \date{January 01, 2015} 18 | \release{1.0} 19 | \author{Tomasz Potanski} 20 | \newcommand{\sphinxlogo}{} 21 | \renewcommand{\releasename}{Release} 22 | \makeindex 23 | 24 | \makeatletter 25 | \def\PYG@reset{\let\PYG@it=\relax \let\PYG@bf=\relax% 26 | \let\PYG@ul=\relax \let\PYG@tc=\relax% 27 | \let\PYG@bc=\relax \let\PYG@ff=\relax} 28 | \def\PYG@tok#1{\csname PYG@tok@#1\endcsname} 29 | \def\PYG@toks#1+{\ifx\relax#1\empty\else% 30 | \PYG@tok{#1}\expandafter\PYG@toks\fi} 31 | \def\PYG@do#1{\PYG@bc{\PYG@tc{\PYG@ul{% 32 | \PYG@it{\PYG@bf{\PYG@ff{#1}}}}}}} 33 | \def\PYG#1#2{\PYG@reset\PYG@toks#1+\relax+\PYG@do{#2}} 34 | 35 | \expandafter\def\csname PYG@tok@gd\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}} 36 | \expandafter\def\csname PYG@tok@gu\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}} 37 | \expandafter\def\csname PYG@tok@gt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}} 38 | \expandafter\def\csname PYG@tok@gs\endcsname{\let\PYG@bf=\textbf} 39 | \expandafter\def\csname PYG@tok@gr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}} 40 | \expandafter\def\csname PYG@tok@cm\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} 41 | \expandafter\def\csname PYG@tok@vg\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} 42 | \expandafter\def\csname PYG@tok@m\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} 43 | \expandafter\def\csname PYG@tok@mh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} 44 | \expandafter\def\csname PYG@tok@cs\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\colorbox[rgb]{1.00,0.94,0.94}{\strut ##1}}} 45 | \expandafter\def\csname PYG@tok@ge\endcsname{\let\PYG@it=\textit} 46 | \expandafter\def\csname PYG@tok@vc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} 47 | \expandafter\def\csname PYG@tok@il\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} 48 | \expandafter\def\csname PYG@tok@go\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.20,0.20,0.20}{##1}}} 49 | \expandafter\def\csname PYG@tok@cp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 50 | \expandafter\def\csname PYG@tok@gi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}} 51 | \expandafter\def\csname PYG@tok@gh\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}} 52 | \expandafter\def\csname PYG@tok@ni\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.84,0.33,0.22}{##1}}} 53 | \expandafter\def\csname PYG@tok@nl\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.13,0.44}{##1}}} 54 | \expandafter\def\csname PYG@tok@nn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} 55 | \expandafter\def\csname PYG@tok@no\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.38,0.68,0.84}{##1}}} 56 | \expandafter\def\csname PYG@tok@na\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 57 | \expandafter\def\csname PYG@tok@nb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 58 | \expandafter\def\csname PYG@tok@nc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.05,0.52,0.71}{##1}}} 59 | \expandafter\def\csname PYG@tok@nd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.33,0.33,0.33}{##1}}} 60 | \expandafter\def\csname PYG@tok@ne\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 61 | \expandafter\def\csname PYG@tok@nf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.49}{##1}}} 62 | \expandafter\def\csname PYG@tok@si\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.44,0.63,0.82}{##1}}} 63 | \expandafter\def\csname PYG@tok@s2\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 64 | \expandafter\def\csname PYG@tok@vi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} 65 | \expandafter\def\csname PYG@tok@nt\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.02,0.16,0.45}{##1}}} 66 | \expandafter\def\csname PYG@tok@nv\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.38,0.84}{##1}}} 67 | \expandafter\def\csname PYG@tok@s1\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 68 | \expandafter\def\csname PYG@tok@gp\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} 69 | \expandafter\def\csname PYG@tok@sh\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 70 | \expandafter\def\csname PYG@tok@ow\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 71 | \expandafter\def\csname PYG@tok@sx\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.78,0.36,0.04}{##1}}} 72 | \expandafter\def\csname PYG@tok@bp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 73 | \expandafter\def\csname PYG@tok@c1\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} 74 | \expandafter\def\csname PYG@tok@kc\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 75 | \expandafter\def\csname PYG@tok@c\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.50,0.56}{##1}}} 76 | \expandafter\def\csname PYG@tok@mf\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} 77 | \expandafter\def\csname PYG@tok@err\endcsname{\def\PYG@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}} 78 | \expandafter\def\csname PYG@tok@kd\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 79 | \expandafter\def\csname PYG@tok@ss\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.32,0.47,0.09}{##1}}} 80 | \expandafter\def\csname PYG@tok@sr\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.14,0.33,0.53}{##1}}} 81 | \expandafter\def\csname PYG@tok@mo\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} 82 | \expandafter\def\csname PYG@tok@mi\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.13,0.50,0.31}{##1}}} 83 | \expandafter\def\csname PYG@tok@kn\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 84 | \expandafter\def\csname PYG@tok@o\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}} 85 | \expandafter\def\csname PYG@tok@kr\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 86 | \expandafter\def\csname PYG@tok@s\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 87 | \expandafter\def\csname PYG@tok@kp\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 88 | \expandafter\def\csname PYG@tok@w\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}} 89 | \expandafter\def\csname PYG@tok@kt\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.56,0.13,0.00}{##1}}} 90 | \expandafter\def\csname PYG@tok@sc\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 91 | \expandafter\def\csname PYG@tok@sb\endcsname{\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 92 | \expandafter\def\csname PYG@tok@k\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.00,0.44,0.13}{##1}}} 93 | \expandafter\def\csname PYG@tok@se\endcsname{\let\PYG@bf=\textbf\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 94 | \expandafter\def\csname PYG@tok@sd\endcsname{\let\PYG@it=\textit\def\PYG@tc##1{\textcolor[rgb]{0.25,0.44,0.63}{##1}}} 95 | 96 | \def\PYGZbs{\char`\\} 97 | \def\PYGZus{\char`\_} 98 | \def\PYGZob{\char`\{} 99 | \def\PYGZcb{\char`\}} 100 | \def\PYGZca{\char`\^} 101 | \def\PYGZam{\char`\&} 102 | \def\PYGZlt{\char`\<} 103 | \def\PYGZgt{\char`\>} 104 | \def\PYGZsh{\char`\#} 105 | \def\PYGZpc{\char`\%} 106 | \def\PYGZdl{\char`\$} 107 | \def\PYGZhy{\char`\-} 108 | \def\PYGZsq{\char`\'} 109 | \def\PYGZdq{\char`\"} 110 | \def\PYGZti{\char`\~} 111 | % for compatibility with earlier versions 112 | \def\PYGZat{@} 113 | \def\PYGZlb{[} 114 | \def\PYGZrb{]} 115 | \makeatother 116 | 117 | \begin{document} 118 | 119 | \maketitle 120 | \tableofcontents 121 | \phantomsection\label{index::doc} 122 | 123 | 124 | Contents: 125 | 126 | 127 | \chapter{Indices and tables} 128 | \label{index:indices-and-tables}\label{index:welcome-to-online-library-management-system-s-documentation}\begin{itemize} 129 | \item {} 130 | \emph{genindex} 131 | 132 | \item {} 133 | \emph{modindex} 134 | 135 | \item {} 136 | \emph{search} 137 | 138 | \end{itemize} 139 | 140 | 141 | 142 | \renewcommand{\indexname}{Index} 143 | \printindex 144 | \end{document} 145 | -------------------------------------------------------------------------------- /doc/_build/latex/onlinelibrarymanagementsystem.toc: -------------------------------------------------------------------------------- 1 | \select@language {english} 2 | \contentsline {chapter}{\numberline {1}Indices and tables}{3}{chapter.1} 3 | -------------------------------------------------------------------------------- /doc/_build/latex/python.ist: -------------------------------------------------------------------------------- 1 | line_max 100 2 | headings_flag 1 3 | heading_prefix " \\bigletter " 4 | 5 | preamble "\\begin{theindex} 6 | \\def\\bigletter#1{{\\Large\\sffamily#1}\\nopagebreak\\vspace{1mm}} 7 | 8 | " 9 | 10 | symhead_positive "{Symbols}" 11 | numhead_positive "{Numbers}" 12 | -------------------------------------------------------------------------------- /doc/_build/latex/sphinx.sty: -------------------------------------------------------------------------------- 1 | % 2 | % sphinx.sty 3 | % 4 | % Adapted from the old python.sty, mostly written by Fred Drake, 5 | % by Georg Brandl. 6 | % 7 | 8 | \NeedsTeXFormat{LaTeX2e}[1995/12/01] 9 | \ProvidesPackage{sphinx}[2010/01/15 LaTeX package (Sphinx markup)] 10 | 11 | \@ifclassloaded{memoir}{}{\RequirePackage{fancyhdr}} 12 | 13 | \RequirePackage{textcomp} 14 | \RequirePackage{fancybox} 15 | \RequirePackage{titlesec} 16 | \RequirePackage{tabulary} 17 | \RequirePackage{amsmath} % for \text 18 | \RequirePackage{makeidx} 19 | \RequirePackage{framed} 20 | \RequirePackage{ifthen} 21 | \RequirePackage{color} 22 | % For highlighted code. 23 | \RequirePackage{fancyvrb} 24 | % For table captions. 25 | \RequirePackage{threeparttable} 26 | % Handle footnotes in tables. 27 | \RequirePackage{footnote} 28 | \makesavenoteenv{tabulary} 29 | % For floating figures in the text. 30 | \RequirePackage{wrapfig} 31 | % Separate paragraphs by space by default. 32 | \RequirePackage{parskip} 33 | % For parsed-literal blocks. 34 | \RequirePackage{alltt} 35 | 36 | % Redefine these colors to your liking in the preamble. 37 | \definecolor{TitleColor}{rgb}{0.126,0.263,0.361} 38 | \definecolor{InnerLinkColor}{rgb}{0.208,0.374,0.486} 39 | \definecolor{OuterLinkColor}{rgb}{0.216,0.439,0.388} 40 | % Redefine these colors to something not white if you want to have colored 41 | % background and border for code examples. 42 | \definecolor{VerbatimColor}{rgb}{1,1,1} 43 | \definecolor{VerbatimBorderColor}{rgb}{1,1,1} 44 | 45 | % Uncomment these two lines to ignore the paper size and make the page 46 | % size more like a typical published manual. 47 | %\renewcommand{\paperheight}{9in} 48 | %\renewcommand{\paperwidth}{8.5in} % typical squarish manual 49 | %\renewcommand{\paperwidth}{7in} % O'Reilly ``Programmming Python'' 50 | 51 | % use pdfoutput for pTeX and dvipdfmx 52 | \ifx\kanjiskip\undefined\else 53 | \ifx\Gin@driver{dvipdfmx.def}\undefined\else 54 | \newcount\pdfoutput\pdfoutput=0 55 | \fi 56 | \fi 57 | 58 | % For graphicx, check if we are compiling under latex or pdflatex. 59 | \ifx\pdftexversion\undefined 60 | \usepackage{graphicx} 61 | \else 62 | \usepackage[pdftex]{graphicx} 63 | \fi 64 | 65 | % for PDF output, use colors and maximal compression 66 | \newif\ifsphinxpdfoutput\sphinxpdfoutputfalse 67 | \ifx\pdfoutput\undefined\else\ifcase\pdfoutput 68 | \let\py@NormalColor\relax 69 | \let\py@TitleColor\relax 70 | \else 71 | \sphinxpdfoutputtrue 72 | \input{pdfcolor} 73 | \def\py@NormalColor{\color[rgb]{0.0,0.0,0.0}} 74 | \def\py@TitleColor{\color{TitleColor}} 75 | \pdfcompresslevel=9 76 | \fi\fi 77 | 78 | % XeLaTeX can do colors, too 79 | \ifx\XeTeXrevision\undefined\else 80 | \def\py@NormalColor{\color[rgb]{0.0,0.0,0.0}} 81 | \def\py@TitleColor{\color{TitleColor}} 82 | \fi 83 | 84 | % Increase printable page size (copied from fullpage.sty) 85 | \topmargin 0pt 86 | \advance \topmargin by -\headheight 87 | \advance \topmargin by -\headsep 88 | 89 | % attempt to work a little better for A4 users 90 | \textheight \paperheight 91 | \advance\textheight by -2in 92 | 93 | \oddsidemargin 0pt 94 | \evensidemargin 0pt 95 | %\evensidemargin -.25in % for ``manual size'' documents 96 | \marginparwidth 0.5in 97 | 98 | \textwidth \paperwidth 99 | \advance\textwidth by -2in 100 | 101 | 102 | % Style parameters and macros used by most documents here 103 | \raggedbottom 104 | \sloppy 105 | \hbadness = 5000 % don't print trivial gripes 106 | 107 | \pagestyle{empty} % start this way 108 | 109 | % Use this to set the font family for headers and other decor: 110 | \newcommand{\py@HeaderFamily}{\sffamily\bfseries} 111 | 112 | % Redefine the 'normal' header/footer style when using "fancyhdr" package: 113 | \@ifundefined{fancyhf}{}{ 114 | % Use \pagestyle{normal} as the primary pagestyle for text. 115 | \fancypagestyle{normal}{ 116 | \fancyhf{} 117 | \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} 118 | \fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}} 119 | \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}} 120 | \fancyhead[LE,RO]{{\py@HeaderFamily \@title, \py@release}} 121 | \renewcommand{\headrulewidth}{0.4pt} 122 | \renewcommand{\footrulewidth}{0.4pt} 123 | % define chaptermark with \@chappos when \@chappos is available for Japanese 124 | \ifx\@chappos\undefined\else 125 | \def\chaptermark##1{\markboth{\@chapapp\space\thechapter\space\@chappos\space ##1}{}} 126 | \fi 127 | } 128 | % Update the plain style so we get the page number & footer line, 129 | % but not a chapter or section title. This is to keep the first 130 | % page of a chapter and the blank page between chapters `clean.' 131 | \fancypagestyle{plain}{ 132 | \fancyhf{} 133 | \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} 134 | \renewcommand{\headrulewidth}{0pt} 135 | \renewcommand{\footrulewidth}{0.4pt} 136 | } 137 | } 138 | 139 | % Some custom font markup commands. 140 | % 141 | \newcommand{\strong}[1]{{\textbf{#1}}} 142 | \newcommand{\code}[1]{\texttt{#1}} 143 | \newcommand{\bfcode}[1]{\code{\bfseries#1}} 144 | \newcommand{\email}[1]{\textsf{#1}} 145 | 146 | % Redefine the Verbatim environment to allow border and background colors. 147 | % The original environment is still used for verbatims within tables. 148 | \let\OriginalVerbatim=\Verbatim 149 | \let\endOriginalVerbatim=\endVerbatim 150 | 151 | % Play with vspace to be able to keep the indentation. 152 | \newlength\distancetoright 153 | \def\mycolorbox#1{% 154 | \setlength\distancetoright{\linewidth}% 155 | \advance\distancetoright -\@totalleftmargin % 156 | \fcolorbox{VerbatimBorderColor}{VerbatimColor}{% 157 | \begin{minipage}{\distancetoright}% 158 | #1 159 | \end{minipage}% 160 | }% 161 | } 162 | \def\FrameCommand{\mycolorbox} 163 | 164 | \renewcommand{\Verbatim}[1][1]{% 165 | % list starts new par, but we don't want it to be set apart vertically 166 | \bgroup\parskip=0pt% 167 | \smallskip% 168 | % The list environement is needed to control perfectly the vertical 169 | % space. 170 | \list{}{% 171 | \setlength\parskip{0pt}% 172 | \setlength\itemsep{0ex}% 173 | \setlength\topsep{0ex}% 174 | \setlength\partopsep{0pt}% 175 | \setlength\leftmargin{0pt}% 176 | }% 177 | \item\MakeFramed {\FrameRestore}% 178 | \small% 179 | \OriginalVerbatim[#1]% 180 | } 181 | \renewcommand{\endVerbatim}{% 182 | \endOriginalVerbatim% 183 | \endMakeFramed% 184 | \endlist% 185 | % close group to restore \parskip 186 | \egroup% 187 | } 188 | 189 | 190 | % \moduleauthor{name}{email} 191 | \newcommand{\moduleauthor}[2]{} 192 | 193 | % \sectionauthor{name}{email} 194 | \newcommand{\sectionauthor}[2]{} 195 | 196 | % Augment the sectioning commands used to get our own font family in place, 197 | % and reset some internal data items: 198 | \titleformat{\section}{\Large\py@HeaderFamily}% 199 | {\py@TitleColor\thesection}{0.5em}{\py@TitleColor}{\py@NormalColor} 200 | \titleformat{\subsection}{\large\py@HeaderFamily}% 201 | {\py@TitleColor\thesubsection}{0.5em}{\py@TitleColor}{\py@NormalColor} 202 | \titleformat{\subsubsection}{\py@HeaderFamily}% 203 | {\py@TitleColor\thesubsubsection}{0.5em}{\py@TitleColor}{\py@NormalColor} 204 | \titleformat{\paragraph}{\small\py@HeaderFamily}% 205 | {\py@TitleColor}{0em}{\py@TitleColor}{\py@NormalColor} 206 | 207 | % {fulllineitems} is the main environment for object descriptions. 208 | % 209 | \newcommand{\py@itemnewline}[1]{% 210 | \@tempdima\linewidth% 211 | \advance\@tempdima \leftmargin\makebox[\@tempdima][l]{#1}% 212 | } 213 | 214 | \newenvironment{fulllineitems}{ 215 | \begin{list}{}{\labelwidth \leftmargin \labelsep 0pt 216 | \rightmargin 0pt \topsep -\parskip \partopsep \parskip 217 | \itemsep -\parsep 218 | \let\makelabel=\py@itemnewline} 219 | }{\end{list}} 220 | 221 | % \optional is used for ``[, arg]``, i.e. desc_optional nodes. 222 | \newcommand{\optional}[1]{% 223 | {\textnormal{\Large[}}{#1}\hspace{0.5mm}{\textnormal{\Large]}}} 224 | 225 | \newlength{\py@argswidth} 226 | \newcommand{\py@sigparams}[2]{% 227 | \parbox[t]{\py@argswidth}{#1\code{)}#2}} 228 | \newcommand{\pysigline}[1]{\item[#1]\nopagebreak} 229 | \newcommand{\pysiglinewithargsret}[3]{% 230 | \settowidth{\py@argswidth}{#1\code{(}}% 231 | \addtolength{\py@argswidth}{-2\py@argswidth}% 232 | \addtolength{\py@argswidth}{\linewidth}% 233 | \item[#1\code{(}\py@sigparams{#2}{#3}]} 234 | 235 | % Production lists 236 | % 237 | \newenvironment{productionlist}{ 238 | % \def\optional##1{{\Large[}##1{\Large]}} 239 | \def\production##1##2{\\\code{##1}&::=&\code{##2}} 240 | \def\productioncont##1{\\& &\code{##1}} 241 | \parindent=2em 242 | \indent 243 | \setlength{\LTpre}{0pt} 244 | \setlength{\LTpost}{0pt} 245 | \begin{longtable}[l]{lcl} 246 | }{% 247 | \end{longtable} 248 | } 249 | 250 | % Notices / Admonitions 251 | % 252 | \newlength{\py@noticelength} 253 | 254 | \newcommand{\py@heavybox}{ 255 | \setlength{\fboxrule}{1pt} 256 | \setlength{\fboxsep}{6pt} 257 | \setlength{\py@noticelength}{\linewidth} 258 | \addtolength{\py@noticelength}{-2\fboxsep} 259 | \addtolength{\py@noticelength}{-2\fboxrule} 260 | %\setlength{\shadowsize}{3pt} 261 | \noindent\Sbox 262 | \minipage{\py@noticelength} 263 | } 264 | \newcommand{\py@endheavybox}{ 265 | \endminipage 266 | \endSbox 267 | \fbox{\TheSbox} 268 | } 269 | 270 | \newcommand{\py@lightbox}{{% 271 | \setlength\parskip{0pt}\par 272 | \noindent\rule[0ex]{\linewidth}{0.5pt}% 273 | \par\noindent\vspace{-0.5ex}% 274 | }} 275 | \newcommand{\py@endlightbox}{{% 276 | \setlength{\parskip}{0pt}% 277 | \par\noindent\rule[0.5ex]{\linewidth}{0.5pt}% 278 | \par\vspace{-0.5ex}% 279 | }} 280 | 281 | % Some are quite plain: 282 | \newcommand{\py@noticestart@note}{\py@lightbox} 283 | \newcommand{\py@noticeend@note}{\py@endlightbox} 284 | \newcommand{\py@noticestart@hint}{\py@lightbox} 285 | \newcommand{\py@noticeend@hint}{\py@endlightbox} 286 | \newcommand{\py@noticestart@important}{\py@lightbox} 287 | \newcommand{\py@noticeend@important}{\py@endlightbox} 288 | \newcommand{\py@noticestart@tip}{\py@lightbox} 289 | \newcommand{\py@noticeend@tip}{\py@endlightbox} 290 | 291 | % Others gets more visible distinction: 292 | \newcommand{\py@noticestart@warning}{\py@heavybox} 293 | \newcommand{\py@noticeend@warning}{\py@endheavybox} 294 | \newcommand{\py@noticestart@caution}{\py@heavybox} 295 | \newcommand{\py@noticeend@caution}{\py@endheavybox} 296 | \newcommand{\py@noticestart@attention}{\py@heavybox} 297 | \newcommand{\py@noticeend@attention}{\py@endheavybox} 298 | \newcommand{\py@noticestart@danger}{\py@heavybox} 299 | \newcommand{\py@noticeend@danger}{\py@endheavybox} 300 | \newcommand{\py@noticestart@error}{\py@heavybox} 301 | \newcommand{\py@noticeend@error}{\py@endheavybox} 302 | 303 | \newenvironment{notice}[2]{ 304 | \def\py@noticetype{#1} 305 | \csname py@noticestart@#1\endcsname 306 | \strong{#2} 307 | }{\csname py@noticeend@\py@noticetype\endcsname} 308 | 309 | % Allow the release number to be specified independently of the 310 | % \date{}. This allows the date to reflect the document's date and 311 | % release to specify the release that is documented. 312 | % 313 | \newcommand{\py@release}{} 314 | \newcommand{\version}{} 315 | \newcommand{\shortversion}{} 316 | \newcommand{\releaseinfo}{} 317 | \newcommand{\releasename}{Release} 318 | \newcommand{\release}[1]{% 319 | \renewcommand{\py@release}{\releasename\space\version}% 320 | \renewcommand{\version}{#1}} 321 | \newcommand{\setshortversion}[1]{% 322 | \renewcommand{\shortversion}{#1}} 323 | \newcommand{\setreleaseinfo}[1]{% 324 | \renewcommand{\releaseinfo}{#1}} 325 | 326 | % Allow specification of the author's address separately from the 327 | % author's name. This can be used to format them differently, which 328 | % is a good thing. 329 | % 330 | \newcommand{\py@authoraddress}{} 331 | \newcommand{\authoraddress}[1]{\renewcommand{\py@authoraddress}{#1}} 332 | 333 | % This sets up the fancy chapter headings that make the documents look 334 | % at least a little better than the usual LaTeX output. 335 | % 336 | \@ifundefined{ChTitleVar}{}{ 337 | \ChNameVar{\raggedleft\normalsize\py@HeaderFamily} 338 | \ChNumVar{\raggedleft \bfseries\Large\py@HeaderFamily} 339 | \ChTitleVar{\raggedleft \textrm{\Huge\py@HeaderFamily}} 340 | % This creates chapter heads without the leading \vspace*{}: 341 | \def\@makechapterhead#1{% 342 | {\parindent \z@ \raggedright \normalfont 343 | \ifnum \c@secnumdepth >\m@ne 344 | \DOCH 345 | \fi 346 | \interlinepenalty\@M 347 | \DOTI{#1} 348 | } 349 | } 350 | } 351 | 352 | % Redefine description environment so that it is usable inside fulllineitems. 353 | % 354 | \renewcommand{\description}{% 355 | \list{}{\labelwidth\z@% 356 | \itemindent-\leftmargin% 357 | \labelsep5pt% 358 | \let\makelabel=\descriptionlabel}} 359 | 360 | % Definition lists; requested by AMK for HOWTO documents. Probably useful 361 | % elsewhere as well, so keep in in the general style support. 362 | % 363 | \newenvironment{definitions}{% 364 | \begin{description}% 365 | \def\term##1{\item[##1]\mbox{}\\*[0mm]} 366 | }{% 367 | \end{description}% 368 | } 369 | 370 | % Tell TeX about pathological hyphenation cases: 371 | \hyphenation{Base-HTTP-Re-quest-Hand-ler} 372 | 373 | 374 | % The following is stuff copied from docutils' latex writer. 375 | % 376 | \newcommand{\optionlistlabel}[1]{\bf #1 \hfill} 377 | \newenvironment{optionlist}[1] 378 | {\begin{list}{} 379 | {\setlength{\labelwidth}{#1} 380 | \setlength{\rightmargin}{1cm} 381 | \setlength{\leftmargin}{\rightmargin} 382 | \addtolength{\leftmargin}{\labelwidth} 383 | \addtolength{\leftmargin}{\labelsep} 384 | \renewcommand{\makelabel}{\optionlistlabel}} 385 | }{\end{list}} 386 | 387 | \newlength{\lineblockindentation} 388 | \setlength{\lineblockindentation}{2.5em} 389 | \newenvironment{lineblock}[1] 390 | {\begin{list}{} 391 | {\setlength{\partopsep}{\parskip} 392 | \addtolength{\partopsep}{\baselineskip} 393 | \topsep0pt\itemsep0.15\baselineskip\parsep0pt 394 | \leftmargin#1} 395 | \raggedright} 396 | {\end{list}} 397 | 398 | % Redefine includgraphics for avoiding images larger than the screen size 399 | % If the size is not specified. 400 | \let\py@Oldincludegraphics\includegraphics 401 | 402 | \newbox\image@box% 403 | \newdimen\image@width% 404 | \renewcommand\includegraphics[2][\@empty]{% 405 | \ifx#1\@empty% 406 | \setbox\image@box=\hbox{\py@Oldincludegraphics{#2}}% 407 | \image@width\wd\image@box% 408 | \ifdim \image@width>\linewidth% 409 | \setbox\image@box=\hbox{\py@Oldincludegraphics[width=\linewidth]{#2}}% 410 | \box\image@box% 411 | \else% 412 | \py@Oldincludegraphics{#2}% 413 | \fi% 414 | \else% 415 | \py@Oldincludegraphics[#1]{#2}% 416 | \fi% 417 | } 418 | 419 | % to make pdf with correct encoded bookmarks in Japanese 420 | % this should precede the hyperref package 421 | \ifx\kanjiskip\undefined\else 422 | \usepackage{atbegshi} 423 | \ifx\ucs\undefined 424 | \ifnum 42146=\euc"A4A2 425 | \AtBeginShipoutFirst{\special{pdf:tounicode EUC-UCS2}} 426 | \else 427 | \AtBeginShipoutFirst{\special{pdf:tounicode 90ms-RKSJ-UCS2}} 428 | \fi 429 | \else 430 | \AtBeginShipoutFirst{\special{pdf:tounicode UTF8-UCS2}} 431 | \fi 432 | \fi 433 | 434 | % Include hyperref last. 435 | \RequirePackage[colorlinks,breaklinks, 436 | linkcolor=InnerLinkColor,filecolor=OuterLinkColor, 437 | menucolor=OuterLinkColor,urlcolor=OuterLinkColor, 438 | citecolor=InnerLinkColor]{hyperref} 439 | % Fix anchor placement for figures with captions. 440 | % (Note: we don't use a package option here; instead, we give an explicit 441 | % \capstart for figures that actually have a caption.) 442 | \RequirePackage{hypcap} 443 | 444 | % From docutils.writers.latex2e 445 | \providecommand{\DUspan}[2]{% 446 | {% group ("span") to limit the scope of styling commands 447 | \@for\node@class@name:=#1\do{% 448 | \ifcsname docutilsrole\node@class@name\endcsname% 449 | \csname docutilsrole\node@class@name\endcsname% 450 | \fi% 451 | }% 452 | {#2}% node content 453 | }% close "span" 454 | } 455 | 456 | \providecommand*{\DUprovidelength}[2]{ 457 | \ifthenelse{\isundefined{#1}}{\newlength{#1}\setlength{#1}{#2}}{} 458 | } 459 | 460 | \DUprovidelength{\DUlineblockindent}{2.5em} 461 | \ifthenelse{\isundefined{\DUlineblock}}{ 462 | \newenvironment{DUlineblock}[1]{% 463 | \list{}{\setlength{\partopsep}{\parskip} 464 | \addtolength{\partopsep}{\baselineskip} 465 | \setlength{\topsep}{0pt} 466 | \setlength{\itemsep}{0.15\baselineskip} 467 | \setlength{\parsep}{0pt} 468 | \setlength{\leftmargin}{#1}} 469 | \raggedright 470 | } 471 | {\endlist} 472 | }{} 473 | 474 | 475 | % From footmisc.sty: allows footnotes in titles 476 | \let\FN@sf@@footnote\footnote 477 | \def\footnote{\ifx\protect\@typeset@protect 478 | \expandafter\FN@sf@@footnote 479 | \else 480 | \expandafter\FN@sf@gobble@opt 481 | \fi 482 | } 483 | \edef\FN@sf@gobble@opt{\noexpand\protect 484 | \expandafter\noexpand\csname FN@sf@gobble@opt \endcsname} 485 | \expandafter\def\csname FN@sf@gobble@opt \endcsname{% 486 | \@ifnextchar[%] 487 | \FN@sf@gobble@twobracket 488 | \@gobble 489 | } 490 | \def\FN@sf@gobble@twobracket[#1]#2{} 491 | 492 | % adjust the margins for footer, 493 | % this works with the jsclasses only (Japanese standard document classes) 494 | \ifx\@jsc@uplatextrue\undefined\else 495 | \hypersetup{setpagesize=false} 496 | \setlength\footskip{2\baselineskip} 497 | \addtolength{\textheight}{-2\baselineskip} 498 | \fi 499 | 500 | % fix the double index and bibliography on the table of contents 501 | % in jsclasses (Japanese standard document classes) 502 | \ifx\@jsc@uplatextrue\undefined\else 503 | \renewcommand{\theindex}{ 504 | \cleardoublepage 505 | \phantomsection 506 | \py@OldTheindex 507 | } 508 | \renewcommand{\thebibliography}[1]{ 509 | \cleardoublepage 510 | \phantomsection 511 | \py@OldThebibliography{1} 512 | } 513 | \fi 514 | 515 | % disable \@chappos in Appendix in pTeX 516 | \ifx\kanjiskip\undefined\else 517 | \let\py@OldAppendix=\appendix 518 | \renewcommand{\appendix}{ 519 | \py@OldAppendix 520 | \gdef\@chappos{} 521 | } 522 | \fi 523 | -------------------------------------------------------------------------------- /doc/_build/latex/sphinxhowto.cls: -------------------------------------------------------------------------------- 1 | % 2 | % sphinxhowto.cls for Sphinx (http://sphinx-doc.org/) 3 | % 4 | 5 | \NeedsTeXFormat{LaTeX2e}[1995/12/01] 6 | \ProvidesClass{sphinxhowto}[2009/06/02 Document class (Sphinx HOWTO)] 7 | 8 | % 'oneside' option overriding the 'twoside' default 9 | \newif\if@oneside 10 | \DeclareOption{oneside}{\@onesidetrue} 11 | % Pass remaining document options to the parent class. 12 | \DeclareOption*{\PassOptionsToClass{\CurrentOption}{\sphinxdocclass}} 13 | \ProcessOptions\relax 14 | 15 | % Default to two-side document 16 | \if@oneside 17 | % nothing to do (oneside is the default) 18 | \else 19 | \PassOptionsToClass{twoside}{\sphinxdocclass} 20 | \fi 21 | 22 | \LoadClass{\sphinxdocclass} 23 | 24 | % Set some sane defaults for section numbering depth and TOC depth. You can 25 | % reset these counters in your preamble. 26 | % 27 | \setcounter{secnumdepth}{2} 28 | 29 | % Change the title page to look a bit better, and fit in with the fncychap 30 | % ``Bjarne'' style a bit better. 31 | % 32 | \renewcommand{\maketitle}{ 33 | \rule{\textwidth}{1pt} 34 | \ifsphinxpdfoutput 35 | \begingroup 36 | % These \defs are required to deal with multi-line authors; it 37 | % changes \\ to ', ' (comma-space), making it pass muster for 38 | % generating document info in the PDF file. 39 | \def\\{, } 40 | \def\and{and } 41 | \pdfinfo{ 42 | /Author (\@author) 43 | /Title (\@title) 44 | } 45 | \endgroup 46 | \fi 47 | \begin{flushright} 48 | \sphinxlogo% 49 | {\rm\Huge\py@HeaderFamily \@title} \par 50 | {\em\large\py@HeaderFamily \py@release\releaseinfo} \par 51 | \vspace{25pt} 52 | {\Large\py@HeaderFamily 53 | \begin{tabular}[t]{c} 54 | \@author 55 | \end{tabular}} \par 56 | \vspace{25pt} 57 | \@date \par 58 | \py@authoraddress \par 59 | \end{flushright} 60 | \@thanks 61 | \setcounter{footnote}{0} 62 | \let\thanks\relax\let\maketitle\relax 63 | %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} 64 | } 65 | 66 | \let\py@OldTableofcontents=\tableofcontents 67 | \renewcommand{\tableofcontents}{ 68 | \begingroup 69 | \parskip = 0mm 70 | \py@OldTableofcontents 71 | \endgroup 72 | \rule{\textwidth}{1pt} 73 | \vspace{12pt} 74 | } 75 | 76 | \@ifundefined{fancyhf}{ 77 | \pagestyle{plain}}{ 78 | \pagestyle{normal}} % start this way; change for 79 | \pagenumbering{arabic} % ToC & chapters 80 | 81 | \thispagestyle{empty} 82 | 83 | % Fix the bibliography environment to add an entry to the Table of 84 | % Contents. 85 | % For an article document class this environment is a section, 86 | % so no page break before it. 87 | \let\py@OldThebibliography=\thebibliography 88 | \renewcommand{\thebibliography}[1]{ 89 | \phantomsection 90 | \py@OldThebibliography{1} 91 | \addcontentsline{toc}{section}{\bibname} 92 | } 93 | 94 | % Same for the indices. 95 | % The memoir class already does this, so we don't duplicate it in that case. 96 | % 97 | \@ifclassloaded{memoir}{}{ 98 | \let\py@OldTheindex=\theindex 99 | \renewcommand{\theindex}{ 100 | \phantomsection 101 | \py@OldTheindex 102 | \addcontentsline{toc}{section}{\indexname} 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /doc/_build/latex/sphinxmanual.cls: -------------------------------------------------------------------------------- 1 | % 2 | % sphinxmanual.cls for Sphinx (http://sphinx-doc.org/) 3 | % 4 | 5 | \NeedsTeXFormat{LaTeX2e}[1995/12/01] 6 | \ProvidesClass{sphinxmanual}[2009/06/02 Document class (Sphinx manual)] 7 | 8 | % chapters starting at odd pages (overridden by 'openany' document option) 9 | \PassOptionsToClass{openright}{\sphinxdocclass} 10 | 11 | % 'oneside' option overriding the 'twoside' default 12 | \newif\if@oneside 13 | \DeclareOption{oneside}{\@onesidetrue} 14 | % Pass remaining document options to the parent class. 15 | \DeclareOption*{\PassOptionsToClass{\CurrentOption}{\sphinxdocclass}} 16 | \ProcessOptions\relax 17 | 18 | % Defaults two-side document 19 | \if@oneside 20 | % nothing to do (oneside is the default) 21 | \else 22 | \PassOptionsToClass{twoside}{\sphinxdocclass} 23 | \fi 24 | 25 | \LoadClass{\sphinxdocclass} 26 | 27 | % Set some sane defaults for section numbering depth and TOC depth. You can 28 | % reset these counters in your preamble. 29 | % 30 | \setcounter{secnumdepth}{2} 31 | \setcounter{tocdepth}{1} 32 | 33 | % Change the title page to look a bit better, and fit in with the fncychap 34 | % ``Bjarne'' style a bit better. 35 | % 36 | \renewcommand{\maketitle}{% 37 | \begin{titlepage}% 38 | \let\footnotesize\small 39 | \let\footnoterule\relax 40 | \rule{\textwidth}{1pt}% 41 | \ifsphinxpdfoutput 42 | \begingroup 43 | % These \defs are required to deal with multi-line authors; it 44 | % changes \\ to ', ' (comma-space), making it pass muster for 45 | % generating document info in the PDF file. 46 | \def\\{, } 47 | \def\and{and } 48 | \pdfinfo{ 49 | /Author (\@author) 50 | /Title (\@title) 51 | } 52 | \endgroup 53 | \fi 54 | \begin{flushright}% 55 | \sphinxlogo% 56 | {\rm\Huge\py@HeaderFamily \@title \par}% 57 | {\em\LARGE\py@HeaderFamily \py@release\releaseinfo \par} 58 | \vfill 59 | {\LARGE\py@HeaderFamily 60 | \begin{tabular}[t]{c} 61 | \@author 62 | \end{tabular} 63 | \par} 64 | \vfill\vfill 65 | {\large 66 | \@date \par 67 | \vfill 68 | \py@authoraddress \par 69 | }% 70 | \end{flushright}%\par 71 | \@thanks 72 | \end{titlepage}% 73 | \cleardoublepage% 74 | \setcounter{footnote}{0}% 75 | \let\thanks\relax\let\maketitle\relax 76 | %\gdef\@thanks{}\gdef\@author{}\gdef\@title{} 77 | } 78 | 79 | 80 | % Catch the end of the {abstract} environment, but here make sure the abstract 81 | % is followed by a blank page if the 'openright' option is used. 82 | % 83 | \let\py@OldEndAbstract=\endabstract 84 | \renewcommand{\endabstract}{ 85 | \if@openright 86 | \ifodd\value{page} 87 | \typeout{Adding blank page after the abstract.} 88 | \vfil\pagebreak 89 | \fi 90 | \fi 91 | \py@OldEndAbstract 92 | } 93 | 94 | % This wraps the \tableofcontents macro with all the magic to get the spacing 95 | % right and have the right number of pages if the 'openright' option has been 96 | % used. This eliminates a fair amount of crud in the individual document files. 97 | % 98 | \let\py@OldTableofcontents=\tableofcontents 99 | \renewcommand{\tableofcontents}{% 100 | \pagenumbering{roman}% 101 | \setcounter{page}{1}% 102 | \pagebreak% 103 | \pagestyle{plain}% 104 | {% 105 | \parskip = 0mm% 106 | \py@OldTableofcontents% 107 | \if@openright% 108 | \ifodd\value{page}% 109 | \typeout{Adding blank page after the table of contents.}% 110 | \pagebreak\hspace{0pt}% 111 | \fi% 112 | \fi% 113 | \cleardoublepage% 114 | }% 115 | \pagenumbering{arabic}% 116 | \@ifundefined{fancyhf}{}{\pagestyle{normal}}% 117 | } 118 | \pagenumbering{alph} 119 | 120 | % This is needed to get the width of the section # area wide enough in the 121 | % library reference. Doing it here keeps it the same for all the manuals. 122 | % 123 | \renewcommand*\l@section{\@dottedtocline{1}{1.5em}{2.6em}} 124 | \renewcommand*\l@subsection{\@dottedtocline{2}{4.1em}{3.5em}} 125 | 126 | % Fix the bibliography environment to add an entry to the Table of 127 | % Contents. 128 | % For a report document class this environment is a chapter. 129 | \let\py@OldThebibliography=\thebibliography 130 | \renewcommand{\thebibliography}[1]{ 131 | \cleardoublepage 132 | \phantomsection 133 | \py@OldThebibliography{1} 134 | \addcontentsline{toc}{chapter}{\bibname} 135 | } 136 | 137 | % Same for the indices. 138 | % The memoir class already does this, so we don't duplicate it in that case. 139 | % 140 | \@ifclassloaded{memoir}{}{ 141 | \let\py@OldTheindex=\theindex 142 | \renewcommand{\theindex}{ 143 | \cleardoublepage 144 | \phantomsection 145 | \py@OldTheindex 146 | \addcontentsline{toc}{chapter}{\indexname} 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /doc/_build/latex/tabulary.sty: -------------------------------------------------------------------------------- 1 | %% 2 | %% This is file `tabulary.sty', 3 | %% generated with the docstrip utility. 4 | %% 5 | %% The original source files were: 6 | %% 7 | %% tabulary.dtx (with options: `package') 8 | %% DRAFT VERSION 9 | %% 10 | %% File `tabulary.dtx'. 11 | %% Copyright (C) 1995 1996 2003 2008 David Carlisle 12 | %% This file may be distributed under the terms of the LPPL. 13 | %% See 00readme.txt for details. 14 | %% 15 | \NeedsTeXFormat{LaTeX2e} 16 | \ProvidesPackage{tabulary} 17 | [2008/12/01 v0.9 tabulary package (DPC)] 18 | \RequirePackage{array} 19 | \catcode`\Z=14 20 | \DeclareOption{debugshow}{\catcode`\Z=9\relax} 21 | \ProcessOptions 22 | \def\arraybackslash{\let\\=\@arraycr} 23 | \def\@finalstrut#1{% 24 | \unskip\ifhmode\nobreak\fi\vrule\@width\z@\@height\z@\@depth\dp#1} 25 | \newcount\TY@count 26 | \def\tabulary{% 27 | \let\TY@final\tabular 28 | \let\endTY@final\endtabular 29 | \TY@tabular} 30 | \def\TY@tabular#1{% 31 | \edef\TY@{\@currenvir}% 32 | {\ifnum0=`}\fi 33 | \@ovxx\TY@linewidth 34 | \@ovyy\TY@tablewidth 35 | \count@\z@ 36 | \@tempswatrue 37 | \@whilesw\if@tempswa\fi{% 38 | \advance\count@\@ne 39 | \expandafter\ifx\csname TY@F\the\count@\endcsname\relax 40 | \@tempswafalse 41 | \else 42 | \expandafter\let\csname TY@SF\the\count@\expandafter\endcsname 43 | \csname TY@F\the\count@\endcsname 44 | \global\expandafter\let\csname TY@F\the\count@\endcsname\relax 45 | \expandafter\let\csname TY@S\the\count@\expandafter\endcsname 46 | \csname TY@\the\count@\endcsname 47 | \fi}% 48 | \global\TY@count\@ne 49 | \TY@width\xdef{0pt}% 50 | \global\TY@tablewidth\z@ 51 | \global\TY@linewidth#1\relax 52 | Z\message{^^J^^JTable^^J% 53 | Z Target Width: \the\TY@linewidth^^J% 54 | Z \string\tabcolsep: \the\tabcolsep\space 55 | Z \string\arrayrulewidth: \the\arrayrulewidth\space 56 | Z \string\doublerulesep: \the\doublerulesep^^J% 57 | Z \string\tymin: \the\tymin\space 58 | Z \string\tymax: \the\tymax^^J}% 59 | \let\@classz\TY@classz 60 | \let\verb\TX@verb 61 | \toks@{}\TY@get@body} 62 | \let\TY@@mkpream\@mkpream 63 | \def\TY@mkpream{% 64 | \def\@addamp{% 65 | \if@firstamp \@firstampfalse \else 66 | \global\advance\TY@count\@ne 67 | \edef\@preamble{\@preamble &}\fi 68 | \TY@width\xdef{0pt}}% 69 | \def\@acol{% 70 | \TY@subwidth\col@sep 71 | \@addtopreamble{\hskip\col@sep}}% 72 | \let\@arrayrule\TY@arrayrule 73 | \let\@classvi\TY@classvi 74 | \def\@classv{\save@decl 75 | \expandafter\NC@ecs\@nextchar\extracolsep{}\extracolsep\@@@ 76 | \sbox\z@{\d@llarbegin\@nextchar\d@llarend}% 77 | \TY@subwidth{\wd\z@}% 78 | \@addtopreamble{\d@llarbegin\the@toks\the\count@\relax\d@llarend}% 79 | \prepnext@tok}% 80 | \global\let\@mkpream\TY@@mkpream 81 | \TY@@mkpream} 82 | \def\TY@arrayrule{% 83 | \TY@subwidth\arrayrulewidth 84 | \@addtopreamble \vline} 85 | \def\TY@classvi{\ifcase \@lastchclass 86 | \@acol \or 87 | \TY@subwidth\doublerulesep 88 | \@addtopreamble{\hskip \doublerulesep}\or 89 | \@acol \or 90 | \@classvii 91 | \fi} 92 | \def\TY@tab{% 93 | \setbox\z@\hbox\bgroup 94 | \let\[$\let\]$% 95 | \let\equation$\let\endequation$% 96 | \col@sep\tabcolsep 97 | \let\d@llarbegin\begingroup\let\d@llarend\endgroup 98 | \let\@mkpream\TY@mkpream 99 | \def\multicolumn##1##2##3{\multispan##1\relax}% 100 | \CT@start\TY@tabarray} 101 | \def\TY@tabarray{\@ifnextchar[{\TY@array}{\@array[t]}} 102 | \def\TY@array[#1]{\@array[t]} 103 | \def\TY@width#1{% 104 | \expandafter#1\csname TY@\the\TY@count\endcsname} 105 | \def\TY@subwidth#1{% 106 | \TY@width\dimen@ 107 | \advance\dimen@-#1\relax 108 | \TY@width\xdef{\the\dimen@}% 109 | \global\advance\TY@linewidth-#1\relax} 110 | \def\endtabulary{% 111 | \gdef\@halignto{}% 112 | \expandafter\TY@tab\the\toks@ 113 | \crcr\omit 114 | {\xdef\TY@save@row{}% 115 | \loop 116 | \advance\TY@count\m@ne 117 | \ifnum\TY@count>\z@ 118 | \xdef\TY@save@row{\TY@save@row&\omit}% 119 | \repeat}\TY@save@row 120 | \endarray\global\setbox1=\lastbox\setbox0=\vbox{\unvbox1 121 | \unskip\global\setbox1=\lastbox}\egroup 122 | \dimen@\TY@linewidth 123 | \divide\dimen@\TY@count 124 | \ifdim\dimen@<\tymin 125 | \TY@warn{tymin too large (\the\tymin), resetting to \the\dimen@}% 126 | \tymin\dimen@ 127 | \fi 128 | \setbox\tw@=\hbox{\unhbox\@ne 129 | \loop 130 | \@tempdima=\lastskip 131 | \ifdim\@tempdima>\z@ 132 | Z \message{ecs=\the\@tempdima^^J}% 133 | \global\advance\TY@linewidth-\@tempdima 134 | \fi 135 | \unskip 136 | \setbox\tw@=\lastbox 137 | \ifhbox\tw@ 138 | Z \message{Col \the\TY@count: Initial=\the\wd\tw@\space}% 139 | \ifdim\wd\tw@>\tymax 140 | \wd\tw@\tymax 141 | Z \message{> max\space}% 142 | Z \else 143 | Z \message{ \@spaces\space}% 144 | \fi 145 | \TY@width\dimen@ 146 | Z \message{\the\dimen@\space}% 147 | \advance\dimen@\wd\tw@ 148 | Z \message{Final=\the\dimen@\space}% 149 | \TY@width\xdef{\the\dimen@}% 150 | \ifdim\dimen@<\tymin 151 | Z \message{< tymin}% 152 | \global\advance\TY@linewidth-\dimen@ 153 | \expandafter\xdef\csname TY@F\the\TY@count\endcsname 154 | {\the\dimen@}% 155 | \else 156 | \expandafter\ifx\csname TY@F\the\TY@count\endcsname\z@ 157 | Z \message{***}% 158 | \global\advance\TY@linewidth-\dimen@ 159 | \expandafter\xdef\csname TY@F\the\TY@count\endcsname 160 | {\the\dimen@}% 161 | \else 162 | Z \message{> tymin}% 163 | \global\advance\TY@tablewidth\dimen@ 164 | \global\expandafter\let\csname TY@F\the\TY@count\endcsname 165 | \maxdimen 166 | \fi\fi 167 | \advance\TY@count\m@ne 168 | \repeat}% 169 | \TY@checkmin 170 | \TY@checkmin 171 | \TY@checkmin 172 | \TY@checkmin 173 | \TY@count\z@ 174 | \let\TY@box\TY@box@v 175 | {\expandafter\TY@final\the\toks@\endTY@final}% 176 | \count@\z@ 177 | \@tempswatrue 178 | \@whilesw\if@tempswa\fi{% 179 | \advance\count@\@ne 180 | \expandafter\ifx\csname TY@SF\the\count@\endcsname\relax 181 | \@tempswafalse 182 | \else 183 | \global\expandafter\let\csname TY@F\the\count@\expandafter\endcsname 184 | \csname TY@SF\the\count@\endcsname 185 | \global\expandafter\let\csname TY@\the\count@\expandafter\endcsname 186 | \csname TY@S\the\count@\endcsname 187 | \fi}% 188 | \TY@linewidth\@ovxx 189 | \TY@tablewidth\@ovyy 190 | \ifnum0=`{\fi}} 191 | \def\TY@checkmin{% 192 | \let\TY@checkmin\relax 193 | \ifdim\TY@tablewidth>\z@ 194 | \Gscale@div\TY@ratio\TY@linewidth\TY@tablewidth 195 | \ifdim\TY@tablewidth <\TY@linewidth 196 | \def\TY@ratio{1}% 197 | \fi 198 | \else 199 | \TY@warn{No suitable columns!}% 200 | \def\TY@ratio{1}% 201 | \fi 202 | \count@\z@ 203 | Z \message{^^JLine Width: \the\TY@linewidth, 204 | Z Natural Width: \the\TY@tablewidth, 205 | Z Ratio: \TY@ratio^^J}% 206 | \@tempdima\z@ 207 | \loop 208 | \ifnum\count@<\TY@count 209 | \advance\count@\@ne 210 | \ifdim\csname TY@F\the\count@\endcsname>\tymin 211 | \dimen@\csname TY@\the\count@\endcsname 212 | \dimen@\TY@ratio\dimen@ 213 | \ifdim\dimen@<\tymin 214 | Z \message{Column \the\count@\space ->}% 215 | \global\expandafter\let\csname TY@F\the\count@\endcsname\tymin 216 | \global\advance\TY@linewidth-\tymin 217 | \global\advance\TY@tablewidth-\csname TY@\the\count@\endcsname 218 | \let\TY@checkmin\TY@@checkmin 219 | \else 220 | \expandafter\xdef\csname TY@F\the\count@\endcsname{\the\dimen@}% 221 | \advance\@tempdima\csname TY@F\the\count@\endcsname 222 | \fi 223 | \fi 224 | Z \dimen@\csname TY@F\the\count@\endcsname\message{\the\dimen@, }% 225 | \repeat 226 | Z \message{^^JTotal:\the\@tempdima^^J}% 227 | } 228 | \let\TY@@checkmin\TY@checkmin 229 | \newdimen\TY@linewidth 230 | \def\tyformat{\everypar{{\nobreak\hskip\z@skip}}} 231 | \newdimen\tymin 232 | \tymin=10pt 233 | \newdimen\tymax 234 | \tymax=2\textwidth 235 | \def\@testpach{\@chclass 236 | \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else 237 | \ifnum \@lastchclass=7 5 \else 238 | \ifnum \@lastchclass=8 \tw@ \else 239 | \ifnum \@lastchclass=9 \thr@@ 240 | \else \z@ 241 | \ifnum \@lastchclass = 10 \else 242 | \edef\@nextchar{\expandafter\string\@nextchar}% 243 | \@chnum 244 | \if \@nextchar c\z@ \else 245 | \if \@nextchar l\@ne \else 246 | \if \@nextchar r\tw@ \else 247 | \if \@nextchar C7 \else 248 | \if \@nextchar L8 \else 249 | \if \@nextchar R9 \else 250 | \if \@nextchar J10 \else 251 | \z@ \@chclass 252 | \if\@nextchar |\@ne \else 253 | \if \@nextchar !6 \else 254 | \if \@nextchar @7 \else 255 | \if \@nextchar <8 \else 256 | \if \@nextchar >9 \else 257 | 10 258 | \@chnum 259 | \if \@nextchar m\thr@@\else 260 | \if \@nextchar p4 \else 261 | \if \@nextchar b5 \else 262 | \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi\fi \fi \fi\fi \fi 263 | \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi \fi} 264 | \def\TY@classz{% 265 | \@classx 266 | \@tempcnta\count@ 267 | \ifx\TY@box\TY@box@v 268 | \global\advance\TY@count\@ne 269 | \fi 270 | \let\centering c% 271 | \let\raggedright\noindent 272 | \let\raggedleft\indent 273 | \let\arraybackslash\relax 274 | \prepnext@tok 275 | \ifnum\@chnum<4 276 | \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ 277 | \fi 278 | \ifnum\@chnum=6 279 | \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ 280 | \fi 281 | \@addtopreamble{% 282 | \ifcase\@chnum 283 | \hfil \d@llarbegin\insert@column\d@llarend \hfil \or 284 | \kern\z@ 285 | \d@llarbegin \insert@column \d@llarend \hfil \or 286 | \hfil\kern\z@ \d@llarbegin \insert@column \d@llarend \or 287 | $\vcenter\@startpbox{\@nextchar}\insert@column \@endpbox $\or 288 | \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or 289 | \vbox \@startpbox{\@nextchar}\insert@column \@endpbox \or 290 | \d@llarbegin \insert@column \d@llarend \or% dubious "s" case 291 | \TY@box\centering\or 292 | \TY@box\raggedright\or 293 | \TY@box\raggedleft\or 294 | \TY@box\relax 295 | \fi}\prepnext@tok} 296 | \def\TY@box#1{% 297 | \ifx\centering#1% 298 | \hfil \d@llarbegin\insert@column\d@llarend \hfil \else 299 | \ifx\raggedright#1% 300 | \kern\z@%<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 301 | \d@llarbegin \insert@column \d@llarend \hfil \else 302 | \ifx\raggedleft#1% 303 | \hfil\kern\z@ \d@llarbegin \insert@column \d@llarend \else 304 | \ifx\relax#1% 305 | \d@llarbegin \insert@column \d@llarend 306 | \fi \fi \fi \fi} 307 | \def\TY@box@v#1{% 308 | \vtop \@startpbox{\csname TY@F\the\TY@count\endcsname}% 309 | #1\arraybackslash\tyformat 310 | \insert@column\@endpbox} 311 | \newdimen\TY@tablewidth 312 | \def\Gscale@div#1#2#3{% 313 | \setlength\dimen@{#3}% 314 | \ifdim\dimen@=\z@ 315 | \PackageError{graphics}{Division by 0}\@eha 316 | \dimen@#2% 317 | \fi 318 | \edef\@tempd{\the\dimen@}% 319 | \setlength\dimen@{#2}% 320 | \count@65536\relax 321 | \ifdim\dimen@<\z@ 322 | \dimen@-\dimen@ 323 | \count@-\count@ 324 | \fi 325 | \loop 326 | \ifdim\dimen@<8192\p@ 327 | \dimen@\tw@\dimen@ 328 | \divide\count@\tw@ 329 | \repeat 330 | \dimen@ii=\@tempd\relax 331 | \divide\dimen@ii\count@ 332 | \divide\dimen@\dimen@ii 333 | \edef#1{\strip@pt\dimen@}} 334 | \long\def\TY@get@body#1\end 335 | {\toks@\expandafter{\the\toks@#1}\TY@find@end} 336 | \def\TY@find@end#1{% 337 | \def\@tempa{#1}% 338 | \ifx\@tempa\TY@\def\@tempa{\end{#1}}\expandafter\@tempa 339 | \else\toks@\expandafter 340 | {\the\toks@\end{#1}}\expandafter\TY@get@body\fi} 341 | \def\TY@warn{% 342 | \PackageWarning{tabulary}} 343 | \catcode`\Z=11 344 | \AtBeginDocument{ 345 | \@ifpackageloaded{colortbl}{% 346 | \expandafter\def\expandafter\@mkpream\expandafter#\expandafter1% 347 | \expandafter{% 348 | \expandafter\let\expandafter\CT@setup\expandafter\relax 349 | \expandafter\let\expandafter\CT@color\expandafter\relax 350 | \expandafter\let\expandafter\CT@do@color\expandafter\relax 351 | \expandafter\let\expandafter\color\expandafter\relax 352 | \expandafter\let\expandafter\CT@column@color\expandafter\relax 353 | \expandafter\let\expandafter\CT@row@color\expandafter\relax 354 | \@mkpream{#1}} 355 | \let\TY@@mkpream\@mkpream 356 | \def\TY@classz{% 357 | \@classx 358 | \@tempcnta\count@ 359 | \ifx\TY@box\TY@box@v 360 | \global\advance\TY@count\@ne 361 | \fi 362 | \let\centering c% 363 | \let\raggedright\noindent 364 | \let\raggedleft\indent 365 | \let\arraybackslash\relax 366 | \prepnext@tok 367 | \expandafter\CT@extract\the\toks\@tempcnta\columncolor!\@nil 368 | \ifnum\@chnum<4 369 | \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ 370 | \fi 371 | \ifnum\@chnum=6 372 | \global\expandafter\let\csname TY@F\the\TY@count\endcsname\z@ 373 | \fi 374 | \@addtopreamble{% 375 | \setbox\z@\hbox\bgroup\bgroup 376 | \ifcase\@chnum 377 | \hskip\stretch{.5}\kern\z@ 378 | \d@llarbegin\insert@column\d@llarend\hskip\stretch{.5}\or 379 | \kern\z@%<<<<<<<<<<<<<<<<<<<<<<<<<<< 380 | \d@llarbegin \insert@column \d@llarend \hfill \or 381 | \hfill\kern\z@ \d@llarbegin \insert@column \d@llarend \or 382 | $\vcenter\@startpbox{\@nextchar}\insert@column \@endpbox $\or 383 | \vtop \@startpbox{\@nextchar}\insert@column \@endpbox \or 384 | \vbox \@startpbox{\@nextchar}\insert@column \@endpbox \or 385 | \d@llarbegin \insert@column \d@llarend \or% dubious s case 386 | \TY@box\centering\or 387 | \TY@box\raggedright\or 388 | \TY@box\raggedleft\or 389 | \TY@box\relax 390 | \fi 391 | \egroup\egroup 392 | \begingroup 393 | \CT@setup 394 | \CT@column@color 395 | \CT@row@color 396 | \CT@do@color 397 | \endgroup 398 | \@tempdima\ht\z@ 399 | \advance\@tempdima\minrowclearance 400 | \vrule\@height\@tempdima\@width\z@ 401 | \unhbox\z@ 402 | }\prepnext@tok}% 403 | \def\TY@arrayrule{% 404 | \TY@subwidth\arrayrulewidth 405 | \@addtopreamble{{\CT@arc@\vline}}}% 406 | \def\TY@classvi{\ifcase \@lastchclass 407 | \@acol \or 408 | \TY@subwidth\doublerulesep 409 | \ifx\CT@drsc@\relax 410 | \@addtopreamble{\hskip\doublerulesep}% 411 | \else 412 | \@addtopreamble{{\CT@drsc@\vrule\@width\doublerulesep}}% 413 | \fi\or 414 | \@acol \or 415 | \@classvii 416 | \fi}% 417 | }{% 418 | \let\CT@start\relax 419 | } 420 | } 421 | {\uccode`\*=`\ % 422 | \uppercase{\gdef\TX@verb{% 423 | \leavevmode\null\TX@vwarn 424 | {\ifnum0=`}\fi\ttfamily\let\\\ignorespaces 425 | \@ifstar{\let~*\TX@vb}{\TX@vb}}}} 426 | \def\TX@vb#1{\def\@tempa##1#1{\toks@{##1}\edef\@tempa{\the\toks@}% 427 | \expandafter\TX@v\meaning\@tempa\\ \\\ifnum0=`{\fi}}\@tempa!} 428 | \def\TX@v#1!{\afterassignment\TX@vfirst\let\@tempa= } 429 | \begingroup 430 | \catcode`\*=\catcode`\# 431 | \catcode`\#=12 432 | \gdef\TX@vfirst{% 433 | \if\@tempa#% 434 | \def\@tempb{\TX@v@#}% 435 | \else 436 | \let\@tempb\TX@v@ 437 | \if\@tempa\space~\else\@tempa\fi 438 | \fi 439 | \@tempb} 440 | \gdef\TX@v@*1 *2{% 441 | \TX@v@hash*1##\relax\if*2\\\else~\expandafter\TX@v@\fi*2} 442 | \gdef\TX@v@hash*1##*2{*1\ifx*2\relax\else#\expandafter\TX@v@hash\fi*2} 443 | \endgroup 444 | \def\TX@vwarn{% 445 | \@warning{\noexpand\verb may be unreliable inside tabularx/y}% 446 | \global\let\TX@vwarn\@empty} 447 | \endinput 448 | %% 449 | %% End of file `tabulary.sty'. 450 | -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # online library management system documentation build configuration file, created by 4 | # sphinx-quickstart on Thu Jan 1 19:10:38 2015. 5 | # 6 | # This file is execfile()d with the current directory set to its 7 | # containing dir. 8 | # 9 | # Note that not all possible configuration values are present in this 10 | # autogenerated file. 11 | # 12 | # All configuration values have a default; values that are commented out 13 | # serve to show the default. 14 | 15 | import sys 16 | import os 17 | 18 | # If extensions (or modules to document with autodoc) are in another directory, 19 | # add these directories to sys.path here. If the directory is relative to the 20 | # documentation root, use os.path.abspath to make it absolute, like shown here. 21 | #sys.path.insert(0, os.path.abspath('.')) 22 | 23 | # -- General configuration ------------------------------------------------ 24 | 25 | # If your documentation needs a minimal Sphinx version, state it here. 26 | #needs_sphinx = '1.0' 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [] 32 | 33 | # Add any paths that contain templates here, relative to this directory. 34 | templates_path = ['_templates'] 35 | 36 | # The suffix of source filenames. 37 | source_suffix = '.txt' 38 | 39 | # The encoding of source files. 40 | #source_encoding = 'utf-8-sig' 41 | 42 | # The master toctree document. 43 | master_doc = 'index' 44 | 45 | # General information about the project. 46 | project = u'online library management system' 47 | copyright = u'2015, Tomasz Potanski' 48 | 49 | # The version info for the project you're documenting, acts as replacement for 50 | # |version| and |release|, also used in various other places throughout the 51 | # built documents. 52 | # 53 | # The short X.Y version. 54 | version = '1.0' 55 | # The full version, including alpha/beta/rc tags. 56 | release = '1.0' 57 | 58 | # The language for content autogenerated by Sphinx. Refer to documentation 59 | # for a list of supported languages. 60 | #language = None 61 | 62 | # There are two options for replacing |today|: either, you set today to some 63 | # non-false value, then it is used: 64 | #today = '' 65 | # Else, today_fmt is used as the format for a strftime call. 66 | #today_fmt = '%B %d, %Y' 67 | 68 | # List of patterns, relative to source directory, that match files and 69 | # directories to ignore when looking for source files. 70 | exclude_patterns = ['_build'] 71 | 72 | # The reST default role (used for this markup: `text`) to use for all 73 | # documents. 74 | #default_role = None 75 | 76 | # If true, '()' will be appended to :func: etc. cross-reference text. 77 | #add_function_parentheses = True 78 | 79 | # If true, the current module name will be prepended to all description 80 | # unit titles (such as .. function::). 81 | #add_module_names = True 82 | 83 | # If true, sectionauthor and moduleauthor directives will be shown in the 84 | # output. They are ignored by default. 85 | #show_authors = False 86 | 87 | # The name of the Pygments (syntax highlighting) style to use. 88 | pygments_style = 'sphinx' 89 | 90 | # A list of ignored prefixes for module index sorting. 91 | #modindex_common_prefix = [] 92 | 93 | # If true, keep warnings as "system message" paragraphs in the built documents. 94 | #keep_warnings = False 95 | 96 | 97 | # -- Options for HTML output ---------------------------------------------- 98 | 99 | # The theme to use for HTML and HTML Help pages. See the documentation for 100 | # a list of builtin themes. 101 | html_theme = 'default' 102 | 103 | # Theme options are theme-specific and customize the look and feel of a theme 104 | # further. For a list of options available for each theme, see the 105 | # documentation. 106 | #html_theme_options = {} 107 | 108 | # Add any paths that contain custom themes here, relative to this directory. 109 | #html_theme_path = [] 110 | 111 | # The name for this set of Sphinx documents. If None, it defaults to 112 | # " v documentation". 113 | #html_title = None 114 | 115 | # A shorter title for the navigation bar. Default is the same as html_title. 116 | #html_short_title = None 117 | 118 | # The name of an image file (relative to this directory) to place at the top 119 | # of the sidebar. 120 | #html_logo = None 121 | 122 | # The name of an image file (within the static path) to use as favicon of the 123 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 124 | # pixels large. 125 | #html_favicon = None 126 | 127 | # Add any paths that contain custom static files (such as style sheets) here, 128 | # relative to this directory. They are copied after the builtin static files, 129 | # so a file named "default.css" will overwrite the builtin "default.css". 130 | html_static_path = ['_static'] 131 | 132 | # Add any extra paths that contain custom files (such as robots.txt or 133 | # .htaccess) here, relative to this directory. These files are copied 134 | # directly to the root of the documentation. 135 | #html_extra_path = [] 136 | 137 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 138 | # using the given strftime format. 139 | #html_last_updated_fmt = '%b %d, %Y' 140 | 141 | # If true, SmartyPants will be used to convert quotes and dashes to 142 | # typographically correct entities. 143 | #html_use_smartypants = True 144 | 145 | # Custom sidebar templates, maps document names to template names. 146 | #html_sidebars = {} 147 | 148 | # Additional templates that should be rendered to pages, maps page names to 149 | # template names. 150 | #html_additional_pages = {} 151 | 152 | # If false, no module index is generated. 153 | #html_domain_indices = True 154 | 155 | # If false, no index is generated. 156 | #html_use_index = True 157 | 158 | # If true, the index is split into individual pages for each letter. 159 | #html_split_index = False 160 | 161 | # If true, links to the reST sources are added to the pages. 162 | #html_show_sourcelink = True 163 | 164 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 165 | #html_show_sphinx = True 166 | 167 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 168 | #html_show_copyright = True 169 | 170 | # If true, an OpenSearch description file will be output, and all pages will 171 | # contain a tag referring to it. The value of this option must be the 172 | # base URL from which the finished HTML is served. 173 | #html_use_opensearch = '' 174 | 175 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 176 | #html_file_suffix = None 177 | 178 | # Output file base name for HTML help builder. 179 | htmlhelp_basename = 'onlinelibrarymanagementsystemdoc' 180 | 181 | 182 | # -- Options for LaTeX output --------------------------------------------- 183 | 184 | latex_elements = { 185 | # The paper size ('letterpaper' or 'a4paper'). 186 | #'papersize': 'letterpaper', 187 | 188 | # The font size ('10pt', '11pt' or '12pt'). 189 | #'pointsize': '10pt', 190 | 191 | # Additional stuff for the LaTeX preamble. 192 | #'preamble': '', 193 | } 194 | 195 | # Grouping the document tree into LaTeX files. List of tuples 196 | # (source start file, target name, title, 197 | # author, documentclass [howto, manual, or own class]). 198 | latex_documents = [ 199 | ('index', 'onlinelibrarymanagementsystem.tex', u'online library management system Documentation', 200 | u'Tomasz Potanski', 'manual'), 201 | ] 202 | 203 | # The name of an image file (relative to this directory) to place at the top of 204 | # the title page. 205 | #latex_logo = None 206 | 207 | # For "manual" documents, if this is true, then toplevel headings are parts, 208 | # not chapters. 209 | #latex_use_parts = False 210 | 211 | # If true, show page references after internal links. 212 | #latex_show_pagerefs = False 213 | 214 | # If true, show URL addresses after external links. 215 | #latex_show_urls = False 216 | 217 | # Documents to append as an appendix to all manuals. 218 | #latex_appendices = [] 219 | 220 | # If false, no module index is generated. 221 | #latex_domain_indices = True 222 | 223 | 224 | # -- Options for manual page output --------------------------------------- 225 | 226 | # One entry per manual page. List of tuples 227 | # (source start file, name, description, authors, manual section). 228 | man_pages = [ 229 | ('index', 'onlinelibrarymanagementsystem', u'online library management system Documentation', 230 | [u'Tomasz Potanski'], 1) 231 | ] 232 | 233 | # If true, show URL addresses after external links. 234 | #man_show_urls = False 235 | 236 | 237 | # -- Options for Texinfo output ------------------------------------------- 238 | 239 | # Grouping the document tree into Texinfo files. List of tuples 240 | # (source start file, target name, title, author, 241 | # dir menu entry, description, category) 242 | texinfo_documents = [ 243 | ('index', 'onlinelibrarymanagementsystem', u'online library management system Documentation', 244 | u'Tomasz Potanski', 'onlinelibrarymanagementsystem', 'One line description of project.', 245 | 'Miscellaneous'), 246 | ] 247 | 248 | # Documents to append as an appendix to all manuals. 249 | #texinfo_appendices = [] 250 | 251 | # If false, no module index is generated. 252 | #texinfo_domain_indices = True 253 | 254 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 255 | #texinfo_show_urls = 'footnote' 256 | 257 | # If true, do not generate a @detailmenu in the "Top" node's menu. 258 | #texinfo_no_detailmenu = False 259 | -------------------------------------------------------------------------------- /doc/index.txt: -------------------------------------------------------------------------------- 1 | .. online library management system documentation master file, created by 2 | sphinx-quickstart on Thu Jan 1 19:10:38 2015. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to online library management system's documentation! 7 | ============================================================ 8 | 9 | Contents: 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | 15 | 16 | Indices and tables 17 | ================== 18 | 19 | * :ref:`genindex` 20 | * :ref:`modindex` 21 | * :ref:`search` 22 | 23 | -------------------------------------------------------------------------------- /library/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library/__init__.py -------------------------------------------------------------------------------- /library/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for library project. 3 | 4 | For more information on this file, see 5 | https://docs.djangoproject.com/en/1.7/topics/settings/ 6 | 7 | For the full list of settings and their values, see 8 | https://docs.djangoproject.com/en/1.7/ref/settings/ 9 | """ 10 | 11 | # Build paths inside the project like this: os.path.join(BASE_DIR, ...) 12 | import dj_database_url 13 | import os 14 | 15 | BASE_DIR = os.path.dirname(os.path.dirname(__file__)) 16 | PROJECT_PATH = os.path.dirname(os.path.abspath(__file__)) 17 | LOGIN_URL = '/' 18 | 19 | 20 | # Quick-start development settings - unsuitable for production 21 | # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ 22 | 23 | # SECURITY WARNING: keep the secret key used in production secret! 24 | SECRET_KEY = 'w7)qdx(89m5*d5zyisy5j9+3sg+@i1*jfddbx^i^2em^@y8rlv' 25 | 26 | # SECURITY WARNING: don't run with debug turned on in production! 27 | DEBUG = True 28 | 29 | TEMPLATE_DEBUG = True 30 | 31 | ALLOWED_HOSTS = [] 32 | 33 | 34 | # Application definition 35 | 36 | INSTALLED_APPS = ( 37 | 'django.contrib.admin', 38 | 'django.contrib.auth', 39 | 'django.contrib.contenttypes', 40 | 'django.contrib.sessions', 41 | 'django.contrib.messages', 42 | 'django.contrib.staticfiles', 43 | 'django_tables2', 44 | 'library_app', 45 | 'fandjango', 46 | 'json_field', 47 | # 'templatetags' 48 | ) 49 | 50 | MIDDLEWARE_CLASSES = ( 51 | 'django.contrib.sessions.middleware.SessionMiddleware', 52 | 'django.middleware.common.CommonMiddleware', 53 | 'django.middleware.csrf.CsrfViewMiddleware', 54 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 55 | 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 56 | 'django.contrib.messages.middleware.MessageMiddleware', 57 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 58 | 'fandjango.middleware.FacebookMiddleware', 59 | 'fandjango.middleware.FacebookWebMiddleware', 60 | ) 61 | 62 | ROOT_URLCONF = 'library.urls' 63 | 64 | WSGI_APPLICATION = 'library.wsgi.application' 65 | 66 | 67 | # Database 68 | # https://docs.djangoproject.com/en/1.7/ref/settings/#databases 69 | 70 | DATABASES = { 71 | 'default': { 72 | # 'ENGINE': 'django.db.backends.sqlite3', 73 | # 'NAME': os.path.join(BASE_DIR, 'sqlite3.db'), 74 | 'ENGINE': 'django.db.backends.postgresql_psycopg2', 75 | 'NAME': 'name', 76 | 'USER': 'username', 77 | 'PASSWORD': 'password', 78 | 'HOST': '', 79 | 'PORT': '', 80 | # 'NAME': os.path.join(BASE_DIR, 'sqlite3.db'), 81 | } 82 | } 83 | 84 | # Internationalization 85 | # https://docs.djangoproject.com/en/1.7/topics/i18n/ 86 | 87 | LANGUAGE_CODE = 'en-us' 88 | 89 | TIME_ZONE = 'UTC' 90 | 91 | USE_I18N = True 92 | 93 | USE_L10N = True 94 | 95 | USE_TZ = True 96 | 97 | 98 | # Static files (CSS, JavaScript, Images) 99 | # https://docs.djangoproject.com/en/1.7/howto/static-files/ 100 | 101 | STATIC_URL = '/static/' 102 | STATIC_ROOT = os.path.join(PROJECT_PATH, 'static') 103 | 104 | TEMPLATE_DIRS = ( 105 | os.path.join(PROJECT_PATH, 'templates'), 106 | ) 107 | 108 | # import dj_database_url 109 | 110 | DATABASES['default'] = dj_database_url.config() 111 | 112 | 113 | TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth", 114 | "django.core.context_processors.debug", 115 | "django.core.context_processors.i18n", 116 | "django.core.context_processors.media", 117 | "django.core.context_processors.static", 118 | "django.contrib.messages.context_processors.messages", 119 | # "library_app.context_processor.is_authenticated" 120 | "django.core.context_processors.request", 121 | ) 122 | 123 | FACEBOOK_APPLICATION_ID = 970424339652057 124 | FACEBOOK_APPLICATION_SECRET_KEY = 'e250adbd77eb67fbf006d7faf08cb66a' 125 | FACEBOOK_APPLICATION_NAMESPACE = 'library_django' 126 | 127 | FANDJANGO_SITE_URL = 'http://django-library.herokuapp.com/fb/' 128 | # FANDJANGO_SITE_URL = 'http://localhost:8888/fb/' 129 | 130 | AUTHENTICATION_BACKENDS = ( 131 | 'django.contrib.auth.backends.ModelBackend', 132 | 'library_app.auth_backend.PasswordlessAuthBackend', 133 | ) -------------------------------------------------------------------------------- /library/templates/about.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with active_tab=about %} 2 | 3 | {% block content %} 4 |
About us
5 |

6 | Lorem ipsum dolor sit amet dolor. Nullam ligula placerat porttitor. Phasellus mollis. Proin volutpat quis, lacinia lacus. Nunc dolor vel mauris rhoncus laoreet hendrerit purus fermentum in, volutpat facilisis, quam at lacus sed est dolor, varius quis, varius eu, leo. In hac habitasse platea dictumst. Vestibulum dolor sit amet, nonummy eget, tincidunt eget, volutpat ante, luctus nibh, sollicitudin lorem, ut venenatis vitae, velit. Duis pretium quis, placerat nec, lacinia eros viverra venenatis nisl. Nam pellentesque sagittis eu, commodo magna, at nulla. Aliquam faucibus gravida sem. Nulla in tortor massa in nunc. Vestibulum ante nec tellus. Cras enim arcu elit, lobortis vitae, quam. Quisque neque tellus, quis lacus. Quisque cursus, nibh ac turpis et nisl. Curabitur condimentum vitae, quam. Fusce vitae eros quis viverra sem at arcu. Cum sociis natoque penatibus et ligula. Nunc a nunc. Quisque cursus odio. Cras ut orci sit amet nunc. Nunc nunc. Maecenas nec sapien dui dolor, placerat pharetra elementum. Aenean et magnis dis parturient montes, nascetur ridiculus mus. Donec euismod orci molestie tristique senectus et mi. Morbi dignissim, libero fermentum ante ipsum dolor eu justo. 7 |

8 | 9 |

10 | Nunc viverra ligula. Cras tortor fringilla fringilla vel, semper risus. Aliquam vel nulla. Aliquam fringilla, massa. Maecenas pretium, diam magna dictum a, mauris. Cras tempus at, cursus vitae, vestibulum lectus at eros ut nulla eu orci blandit ultrices iaculis. Curabitur interdum. Quisque consectetuer adipiscing elit. Nam eu pede eu auctor sapien. Aenean sodales, velit sit amet dolor. Aenean augue nec egestas at, consequat sed, imperdiet lectus feugiat fermentum wisi, aliquam arcu. Suspendisse eu nisl. Etiam leo mollis eu, posuere cubilia Curae, Nulla posuere ante ipsum dolor in massa. Nulla nunc iaculis nec, elementum dui. Morbi massa molestie augue commodo ante. Maecenas vitae risus dictum wisi accumsan eget, condimentum ac, suscipit id, luctus et lacus scelerisque lorem leo, pretium nec, mattis magna. Curabitur vel lectus. Nulla lobortis facilisis. Phasellus placerat pharetra velit vitae erat. Quisque in augue. Fusce commodo et, varius ac, eros. Aliquam bibendum, urna accumsan odio vitae convallis quam ac elit at porta scelerisque, dui nulla, rutrum ligula, egestas imperdiet orci id justo ac quam accumsan congue, lorem pretium wisi. Aenean feugiat dui, non ipsum. Aliquam vitae ligula eleifend. 11 |

12 | 13 |

14 | Nullam vitae felis. Nullam volutpat, libero vel dui aliquam risus nunc, nonummy turpis. Mauris pellentesque, justo orci ac erat velit lectus felis risus at elit sed justo. Phasellus sagittis sed, ullamcorper aliquam. Nunc convallis pellentesque, justo a wisi. Integer est. Pellentesque habitant morbi tristique luctus augue. Sed eros. Nullam pharetra leo. Sed a odio vitae arcu vel lorem. Maecenas rhoncus. Praesent blandit lobortis. Maecenas bibendum ipsum ut orci dictum lectus nec augue. Donec at elit justo quis faucibus orci ipsum, rutrum rhoncus. Praesent gravida sit amet, consectetuer ut, magna. Sed tempus leo mollis sodales. Vivamus malesuada neque odio eget leo. Cras tortor orci, aliquam turpis. Lorem ipsum primis in dui. Morbi hendrerit. Sed in consequat auctor dignissim. Morbi egestas, orci ipsum, vel hendrerit nonummy. Class aptent taciti sociosqu ad litora torquent per inceptos hymenaeos. Maecenas scelerisque arcu. Morbi justo. Maecenas gravida, erat sem orci, blandit justo, condimentum vitae, pede. Donec sit amet augue. Cum sociis natoque penatibus et quam. Cum sociis natoque penatibus et ultrices posuere cubilia Curae, Nulla mollis faucibus, erat metus eros ipsum, congue quis, luctus quis, placerat. 15 |

16 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/author_show.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with active_tab=books small_panel=true center_panel_content=true %} 3 | 4 | {% block content %} 5 |
{{ author.name|title }} {{ author.surname|title }}
6 |
7 | 8 | Name: {{ author.name }}
9 | Surname: {{ author.surname }}
10 | Date of birth: {{ author.date_of_birth }}
11 | 12 | 13 |
14 | {# List books by this author #} 15 | {% if books_qs.count > 0 %} 16 | {% autoescape off %} 17 | {% render_table books_table "table_without_footer.html" %} 18 | {% endautoescape %} 19 | {% endif %} 20 | 21 | List of authors

22 | 23 | {% if request.user|has_group:"Librarians" %} 24 | 30 | {% else %} 31 | {% endif %} 32 | 33 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/authors.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with vcenter_panel=true active_tab=books %} 3 | 4 | 5 | 6 | {% block content %} 7 | 8 | 18 | {% autoescape off %} 19 | {% render_table authors_table "table_without_footer.html" %} 20 | {% endautoescape %} 21 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/base.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | {% block title %} 14 | Online Library System 15 | {% endblock %} 16 | 17 | 18 | 19 | 20 | {% block include %} 21 | {% endblock %} 22 | 23 | 24 | 25 | 26 |
27 |
28 |
29 | 30 | 70 | 71 |
72 | {% block site %} 73 | {% block flash %} 74 | {% if auth_form.non_field_errors or user_form.non_field_errors %} 75 |
76 | {{ auth_form.non_field_errors }} 77 | {{ user_form.non_field_errors }} 78 |
79 | {% endif %} 80 | {% if notice %} 81 |
82 | {{ notice }} 83 |
84 | {% endif %} 85 | {% endblock %} 86 | 87 | 88 | {% if messages %} 89 | {% for message in messages %} 90 |
91 | {{ message }} 92 |
93 | {% endfor %} 94 | {% endif %} 95 | 96 | {% block menu-left %} 97 | {% endblock %} 98 | 99 | {% block content_outside_div %} 100 | 101 |
102 |
103 |
104 | 105 | {% block content %} 106 | Content 107 | {% endblock %} 108 |
109 |
110 |
111 | {% endblock %} 112 | 113 |
{% endblock %} 114 | 115 |
116 | 117 | 118 | 119 | 130 | 131 | 132 |
133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | {% block include_footer %} 142 | {% endblock %} 143 | 144 | 145 | -------------------------------------------------------------------------------- /library/templates/book_show.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with active_tab=books small_panel=true center_panel_content=true %} 3 | 4 | {% block content %} 5 |
{{ book.title|title }}
6 |
7 | 8 | Title: {{ book.title }}
9 | ISBN: {{ book.ISBN }}
10 | {{ book.publisher }}
11 | {{ book.author }}
12 | Lend period: {{ book.lend_period }}
13 | Page amount: {{ book.page_amount }}
14 | Available: 15 | {% if book.lend_by != None %} 16 | No 17 | {% else %} 18 | Yes, Borrow it! 19 | {% endif %} 20 | 21 |
22 | 23 | List of books

24 | {% if pbu == "true" %} 25 | You have this book! Write down a few quotations: 26 | 27 | 28 | 32 | {% endif %} 33 | 34 | {% if request.user|has_group:"Librarians" %} 35 |
    36 | 37 |
  • Edit this book
  • 38 | 39 |
  • Remove 41 | this book
  • 42 | 43 | 44 | {% if book.lend_by != None %} 45 |
  • Mark this book as returned.
  • 46 | {% endif %} 47 |
48 | {% else %} 49 | {% endif %} 50 | 51 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/books.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with vcenter_panel=true active_tab=books %} 3 | 4 | 5 | 6 | {% block content %} 7 | 8 | 31 | {% autoescape off %} 32 | {% render_table books_table "table_without_footer.html" %} 33 | {% endautoescape %} 34 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/change_password.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with active_tab=profile %} 2 | 3 | {% block content %} 4 | 5 | 6 |

7 |

17 | 18 |

19 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/home.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with active_tab=home %} 2 | 3 | {% block content %} 4 |
Welcome: {{ user.username }}
5 | 6 |
7 | {% block fb_messages %} 8 | {% endblock %} 9 |


10 | 11 | 12 |
13 | 24 |
25 | 26 |
27 | 28 | 29 | {% if count > 0 %} 30 |

31 | {% for f, q, author, nr in friends_quotations %} 32 |

41 | {% endfor %} 42 |

43 | {% endif %} 44 | 45 | 46 | {% if count == 0 %} To see animated quotations add a few friends. Add now 47 | ;){% endif %} 48 | {% endblock %} 49 | 50 | -------------------------------------------------------------------------------- /library/templates/my_quotations.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with small_panel=true vcenter_panel=true active_tab=quotations %} 2 | 3 | 4 | 5 | {% block content %} 6 | 7 | 8 |
My saved quotations:
9 |

10 | {% if quotations %} 11 |

    12 | {% for q in quotations %} 13 |
  • "{{ q.quotation }}" by: 14 | {{ q.book.title }}
  • 15 | {% endfor %} 16 |
17 | {% endif %} 18 |

19 | 20 | {% if quotations %} 21 | 36 | {% else %} 37 | You do not have any quotations saved... 38 | {% endif %} 39 | 40 | 41 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/new.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with small_panel=true vcenter_panel=true active_tab=sign_in %} 2 | 3 | 4 | 5 | {% block content %} 6 | 7 | 26 | 27 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/period_show.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with active_tab=books small_panel=true center_panel_content=true %} 3 | 4 | {% block content %} 5 |
{{ period.name|title }}
7 |
8 | 9 | Name: {{ period.name }}
10 | Amount of days: {{ period.days_amount }}
11 | 12 |
13 | 14 | List of periods
15 | 16 | {% if request.user|has_group:"Librarians" %} 17 | 18 | 24 | {% else %} 25 | {% endif %} 26 | 27 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/periods.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with vcenter_panel=true active_tab=books %} 3 | 4 | 5 | 6 | {% block content %} 7 | 8 | 18 | {% autoescape off %} 19 | {% render_table periods_table "table_without_footer.html" %} 20 | {% endautoescape %} 21 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/public_home.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with active_tab=home %} 2 | 3 | {% block include %} 4 | 5 | {# comment #} 6 | 7 | 11 | {# endcomment #} 12 | {% endblock %} 13 | 14 | {% block include_footer %} 15 | 16 | {% endblock %} 17 | 18 | {% block site %} 19 | 20 |
21 | 23 | 71 | 72 | 73 | 75 | 76 | 77 |
78 | 79 |

Meet our team!

80 | 81 |
82 |
83 | Generic placeholder image 85 |

Heading

86 |

Donec sed odio dui. Etiam porta sem malesuada magna mollis euismod. Nullam id dolor id nibh ultricies vehicula ut id elit. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Praesent commodo cursus magna.

87 |

View details »

88 |
89 |
90 | Generic placeholder image 91 |

Heading

92 |

Duis mollis, est non commodo luctus, nisi erat porttitor ligula, eget lacinia odio sem nec elit. Cras mattis consectetur purus sit amet fermentum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh.

93 |

View details »

94 |
95 |
96 | Generic placeholder image 97 |

Heading

98 |

Donec sed odio dui. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Vestibulum id ligula porta felis euismod semper. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

99 |

View details »

100 |
101 |
102 | 103 | 104 | 105 | 106 |
107 |
108 |
109 |

First featurette heading.

110 |

Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

111 |
112 |
113 | 114 |
115 | 116 |
117 | 118 | 119 |
120 |
121 | 122 |
123 |
124 |

Oh yeah, it's that good. See for yourself.

125 |

Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

126 |
127 |
128 | 129 | 130 |
131 |
132 |

And lastly, this one. Checkmate.

133 |

Donec ullamcorper nulla non metus auctor fringilla. Vestibulum id ligula porta felis euismod semper. Praesent commodo cursus magna, vel scelerisque nisl consectetur. Fusce dapibus, tellus ac cursus commodo.

134 |
135 |
136 | 137 |
138 |
139 | 140 | 141 | 142 |
143 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/publisher_show.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with active_tab=books small_panel=true center_panel_content=true %} 3 | 4 | {% block content %} 5 |
{{ publisher.name|title }}
7 |
8 | 9 | Name: {{ publisher.name }}

10 | 11 |
12 | {# List books by this publisher #} 13 | {% if books_qs.count > 0 %} 14 | List books by this publisher:

15 | {% autoescape off %} 16 | {% render_table books_table "table_without_footer.html" %} 17 | {% endautoescape %} 18 | {% endif %} 19 | 20 | List of publishers

21 | 22 | {% if request.user|has_group:"Librarians" %} 23 | 24 | 30 | {% else %} 31 | {% endif %} 32 | 33 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/publishers.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with vcenter_panel=true active_tab=books %} 3 | 4 | 5 | 6 | {% block content %} 7 | 8 | 18 | {% autoescape off %} 19 | {% render_table publishers_table "table_without_footer.html" %} 20 | {% endautoescape %} 21 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/search_users.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with vcenter_panel=true active_tab=books %} 3 | 4 | 5 | 6 | {% block content %} 7 | 8 | 18 | {% autoescape off %} 19 | {% render_table users_table "table_without_footer.html" %} 20 | {% endautoescape %} 21 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/sign_in.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with small_panel=true vcenter_panel=true active_tab=sign_in %} 2 | 3 | 4 | 5 | {% block content %} 6 | 7 | 14 | 15 | 20 | 21 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/sign_up.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with vcenter_panel=true small_panel=true active_tab=sign_up %} 2 | 3 | {% block content %} 4 | 5 | 6 | 20 | 21 |
or

22 | 23 | 24 | 33 | 34 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/table_without_footer.html: -------------------------------------------------------------------------------- 1 | {% extends "django_tables2/table.html" %} 2 | 3 | {% block pagination.cardinality %} 4 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/user.html: -------------------------------------------------------------------------------- 1 | {% load django_tables2 %} 2 | {% xextends "base.html" with active_tab=profile small_panel=true center_panel_content=true %} 3 | 4 | {% block content %} 5 |
{{ this_user.username|title }}{% if not other_user %}, edit your profile! {% endif %} 6 |
7 |
8 | {% if this_user.email|length > 0 and this_user.email != None %}

{% endif %} 9 |
10 | 11 | Username: {{ this_user.username }}
12 | Email: {% if this_user.email|length > 0 and this_user.email != None %} {{ this_user.email }} {% else %} -<Blank>- {% endif %}
13 | First name: {% if this_user.first_name|length > 0 and this_user.first_name != None %} {{ this_user.first_name }} {% else %} -<Blank>- {% endif %}
14 | Last name: {% if this_user.last_name|length > 0 and this_user.last_name != None %} {{ this_user.last_name }} {% else %} -<Blank>- {% endif %}
15 | 16 | Mobile: {% if this_user.profile.mobile|length > 0 and this_user.profile.mobile != None %} {{ this_user.profile.mobile }} {% else %} -<Blank>- {% endif %}
17 | Website: {% if this_user.profile.website|length > 0 and this_user.profile.website != None %} {{ this_user.profile.website }} {% else %} -<Blank>- {% endif %}
18 | Join date: {% if this_user.profile.join_date|length > 0 and this_user.profile.join_date != None %} {{ this_user.profile.join_date }} {% else %} -<Blank>- {% endif %}

19 | 20 | {% if not other_user %}Do you want to change password?{% endif %} 21 | 22 | {% if other_user %} 23 | {% if other_is_friend %}You are friends! (Unfriend) 24 | {% else %}You are not friends yet. (Befriend) 25 | {% endif %} 26 | {% endif %} 27 | 28 | 29 |
30 | {% if this_user.profile.friends.all %} 31 |

{% if not other_user %}Your{% else %}His/Her{% endif %} friends 32 | {% if not other_user %}(add more){% endif %}: 33 | {% autoescape off %} 34 | {% render_table friends_table "table_without_footer.html" %} 35 | {% endautoescape %} 36 | {% else %} 37 |

{% if not other_user %}You have{% else %}He/She has{% endif %} not added friends yet! 38 | {% if not other_user %}Add some ;){% endif %} 39 | {% endif %} 40 |
41 | 42 | {% if other_is_friend or not other_user %} 43 | {% if books_qs %} 44 |

{% if not other_user %}Your{% else %}His/Her{% endif %} books: 45 | {% autoescape off %} 46 | {% render_table books_table "table_without_footer.html" %} 47 | {% endautoescape %} 48 | {% else %} 49 |

{% if not other_user %}You do{% else %}He/She does{% endif %} not have books! 50 | {% if not other_user %} Borrow some ;) {% endif %} 51 | {% endif %} 52 | {% endif %} 53 | 54 |

55 | {% if other_user and other_is_friend %} 56 | 57 | {% if quotations %} 58 |
    59 | His/Her saved quotations: 60 | {% for q in quotations %} 61 |
  • "{{ q.quotation }}" by: 62 | {{ q.book.title }}
  • 63 | {% endfor %} 64 |
65 | {% endif %} 66 |

67 | 68 | {% if quotations %} 69 | 84 | {% else %} 85 | He/She do not have any quotations saved... 86 | {% endif %} 87 | {% endif %} 88 | 89 | 90 | {% if not other_user and request.user|has_group:"Librarians" %} 91 |
92 |
Librarian dashboard
93 |

94 |

106 |

107 | {% else %} 108 | {% endif %} 109 | 110 | {% endblock %} -------------------------------------------------------------------------------- /library/templates/useredit.html: -------------------------------------------------------------------------------- 1 | {% xextends "base.html" with active_tab=profile %} 2 | 3 | {% block content %} 4 | 5 | 12 | 13 | {% endblock %} -------------------------------------------------------------------------------- /library/urls.py: -------------------------------------------------------------------------------- 1 | from django.conf.urls import patterns, include, url 2 | from django.contrib import admin 3 | 4 | urlpatterns = patterns('', 5 | # Examples: 6 | # url(r'^$', 'library.views.home', name='home'), 7 | # url(r'^blog/', include('blog.urls')), 8 | 9 | #public urls 10 | url(r'^$', 'library_app.views.home', name='home'), 11 | url(r'^about/$', 'library_app.views.about', name='about'), 12 | url(r'^sign_in/$', 'library_app.views.sign_in', name='sign_in'), 13 | url(r'^sign_up/$', 'library_app.views.sign_up', name='sign_up'), 14 | url(r'^logout/$', 'library_app.views.logout_view', name='logout'), 15 | 16 | #only for authorized users 17 | url(r'^my_quotations/$', 'library_app.views.user_quotations', name='user_quotations'), 18 | 19 | #books 20 | url(r'^books/$', 'library_app.views.books', name='books'), 21 | url(r'^books/show/(?P\w{0,5})/$', 'library_app.views.books_show', name='books_show'), 22 | url(r'^books/borrow/(?P\w{0,5})/$', 'library_app.views.borrow_book', name='borrow_book'), 23 | url(r'^books/return/(?P\w{0,5})/$', 'library_app.views.return_book', name='return_book'), 24 | 25 | #authors 26 | url(r'^authors/$', 'library_app.views.authors', name='authors'), 27 | url(r'^authors/show/(?P\w{0,5})/$', 'library_app.views.authors_show', name='authors_show'), 28 | 29 | #users 30 | url(r'^change_password/$', 'library_app.views.change_password', name='change_password'), 31 | url(r'^users/$', 'library_app.views.search_users', name='search_users'), 32 | url(r'^users/(?P\d{1})/(?P\w{0,30})/$', 'library_app.views.user_connect', name='user_connect'), 33 | url(r'^users/(?P\w{0,30})/$', 'library_app.views.user', name='user'), 34 | url(r'^useredit/$', 'library_app.views.useredit', name='useredit'), 35 | 36 | #publishers 37 | url(r'^publishers/$', 'library_app.views.publishers', name='publishers'), 38 | url(r'^publishers/show/(?P\w{0,5})/$', 'library_app.views.publishers_show', name='publishers_show'), 39 | 40 | #periods 41 | url(r'^periods/$', 'library_app.views.periods', name='periods'), 42 | url(r'^periods/show/(?P\w{0,5})/$', 'library_app.views.periods_show', name='periods_show'), 43 | 44 | #CRUD 45 | url(r'^(?P\w{1,10})/new/$', 'library_app.views.create_instance', name='new'), 46 | url(r'^(?P\w{1,10})/edit/(?P\d{1,10})$', 'library_app.views.edit_instance', name='edit'), 47 | url(r'^(?P\w{1,10})/remove/(?P\d{1,10})$', 'library_app.views.remove_instance', name='remove'), 48 | 49 | url(r'^admin/', include(admin.site.urls)), 50 | 51 | #facebook 52 | url(r'^fandjango/', include('fandjango.urls')), 53 | url(r'^fb/(?P\w{1,10})$', 'library_app.views.fb_sign_up', name='fb_sign_up'), 54 | ) 55 | 56 | #static files 57 | urlpatterns += patterns('django.contrib.staticfiles.views', 58 | url(r'^static/(?P.*)$', 'serve'), 59 | ) 60 | -------------------------------------------------------------------------------- /library/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for library project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/1.7/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "library.settings") 12 | 13 | from django.core.wsgi import get_wsgi_application 14 | application = get_wsgi_application() 15 | -------------------------------------------------------------------------------- /library_app/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/__init__.py -------------------------------------------------------------------------------- /library_app/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from .models import * 3 | 4 | 5 | admin.site.register(Author) 6 | # admin.site.register(Publisher) 7 | # admin.site.register(LendPeriods) 8 | # admin.site.register(Book) 9 | # admin.site.register(UserProfile) 10 | # admin.site.register(QuotationFromBook) 11 | -------------------------------------------------------------------------------- /library_app/auth_backend.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.backends import ModelBackend 2 | from django.contrib.auth.models import User 3 | 4 | 5 | class PasswordlessAuthBackend(ModelBackend): 6 | """ 7 | Log in to Django without providing a password. 8 | Applied for facebook authentication. 9 | """ 10 | def authenticate(self, username=None): 11 | try: 12 | return User.objects.get(username=username) 13 | except User.DoesNotExist: 14 | return None 15 | 16 | def get_user(self, user_id): 17 | try: 18 | return User.objects.get(pk=user_id) 19 | except User.DoesNotExist: 20 | return None -------------------------------------------------------------------------------- /library_app/context_processor.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /library_app/decorators/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/decorators/__init__.py -------------------------------------------------------------------------------- /library_app/decorators/group_required.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.decorators import user_passes_test 2 | 3 | 4 | def group_required(*group_names): 5 | """Requires user membership in at least one of the groups passed in.""" 6 | def in_groups(u): 7 | if u.is_authenticated(): 8 | if bool(u.groups.filter(name__in=group_names)) | u.is_superuser: 9 | return True 10 | return False 11 | return user_passes_test(in_groups) -------------------------------------------------------------------------------- /library_app/fixtures/users.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "fields": { 4 | "username": "potan", 5 | "first_name": "Tomasz", 6 | "last_name": "Potanski", 7 | "is_active": true, 8 | "is_superuser": true, 9 | "is_staff": true, 10 | "last_login": "2014-12-31T17:31:09.318Z", 11 | "groups": [], 12 | "user_permissions": [], 13 | "password": "pbkdf2_sha256$12000$72SIz2cZFZQJ$ZNZv9ygwUwu8VdBP/OfReI64diEggPQNsVHwKgZXkuc=", 14 | "email": "tomasz@potanski.pl", 15 | "date_joined": "2014-11-26T08:57:01Z" 16 | }, 17 | "model": "auth.user", 18 | "pk": 1 19 | }, 20 | { 21 | "fields": { 22 | "username": "user1", 23 | "first_name": "Joanna", 24 | "last_name": "Binkowska", 25 | "is_active": true, 26 | "is_superuser": false, 27 | "is_staff": false, 28 | "last_login": "2014-12-28T16:50:28.911Z", 29 | "groups": [], 30 | "user_permissions": [], 31 | "password": "pbkdf2_sha256$12000$Dj6JKxDJNSzm$CEzMz+5Suon7V7Hl1i2z+515AON3PSTLywbxVu6A1M0=", 32 | "email": "malgosia.szwed@gmail.com", 33 | "date_joined": "2014-12-18T12:44:26Z" 34 | }, 35 | "model": "auth.user", 36 | "pk": 4 37 | }, 38 | { 39 | "fields": { 40 | "username": "assistant", 41 | "first_name": "John", 42 | "last_name": "Smith", 43 | "is_active": true, 44 | "is_superuser": false, 45 | "is_staff": false, 46 | "last_login": "2014-12-31T16:01:02.848Z", 47 | "groups": [ 48 | 1 49 | ], 50 | "user_permissions": [], 51 | "password": "pbkdf2_sha256$12000$fRjiz2ujAyHk$OTRcGIZsmuRozxqVSxD/mHL8PRNnyKvXwZiSK9qCqIM=", 52 | "email": "suwmifogeh@gmail.com", 53 | "date_joined": "2014-12-27T16:21:21Z" 54 | }, 55 | "model": "auth.user", 56 | "pk": 5 57 | }, 58 | { 59 | "fields": { 60 | "username": "Arkadiusz_1375943392708267", 61 | "first_name": "Arkadiusz", 62 | "last_name": "G\u0142owacki", 63 | "is_active": true, 64 | "is_superuser": false, 65 | "is_staff": false, 66 | "last_login": "2014-12-29T23:57:00.102Z", 67 | "groups": [], 68 | "user_permissions": [], 69 | "password": "pbkdf2_sha256$12000$RC1sumyksWDY$8GHPDhz+VmEhMWKIK88KanaVg7sJfMCpcqE2e6yS+Jk=", 70 | "email": "", 71 | "date_joined": "2014-12-29T23:42:08.067Z" 72 | }, 73 | "model": "auth.user", 74 | "pk": 7 75 | } 76 | ] 77 | -------------------------------------------------------------------------------- /library_app/forms.py: -------------------------------------------------------------------------------- 1 | from django.contrib.auth.forms import AuthenticationForm, UserCreationForm 2 | from django import forms 3 | from django.utils.html import strip_tags 4 | from .models import UserProfile, User, Author, Publisher, LendPeriods, Book 5 | from .validators import email_vailidator 6 | from django.utils import timezone 7 | from django.forms import ModelForm 8 | 9 | 10 | class UserEditForm(forms.Form): 11 | """ 12 | Form for editing User instances 13 | """ 14 | username = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Username'})) 15 | email = forms.EmailField(validators=[email_vailidator], required=False, widget=forms.widgets.EmailInput(attrs={'placeholder': 'Email'})) 16 | first_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'First Name'})) 17 | last_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Last Name'})) 18 | 19 | mobile = forms.CharField(required=False, widget=forms.widgets.TextInput(attrs={'placeholder': 'Mobile No.'})) 20 | website = forms.CharField(required=False, widget=forms.widgets.URLInput(attrs={'placeholder': 'Website address'})) 21 | 22 | def __init__(self, *args, **kwargs): 23 | super(UserEditForm, self).__init__(*args, **kwargs) 24 | self.fields['username'].widget.attrs['readonly'] = True 25 | 26 | class Meta: 27 | fields = ['username', 'email', 'first_name', 'last_name', 'mobile', 'website'] 28 | 29 | def is_valid(self): 30 | 31 | valid = super(UserEditForm, self).is_valid() 32 | # we're done now if not valid 33 | if not valid: 34 | return valid 35 | 36 | for f, error in self.errors.iteritems(): 37 | if f != '__all_': 38 | self.fields[f].widget.attrs.update({'class': 'error', 'value': strip_tags(error)}) 39 | return self 40 | 41 | def clean_email(self): 42 | username = self.cleaned_data.get('username') 43 | email = self.cleaned_data.get('email') 44 | 45 | if email and User.objects.filter(email=email).exclude(username=username).count(): 46 | e = forms.ValidationError( 47 | 'This email address is already in use. Please supply a different email address.') 48 | raise e 49 | return email 50 | 51 | def save(self, user): 52 | user.email = self.cleaned_data.get('email') 53 | 54 | user.first_name = self.cleaned_data.get('first_name') 55 | user.last_name = self.cleaned_data.get('last_name') 56 | user.profile.mobile = self.cleaned_data.get('mobile') 57 | user.profile.website = self.cleaned_data.get('website') 58 | user.profile.save() 59 | user.save() 60 | return user 61 | 62 | 63 | class UserCreateForm(UserCreationForm): 64 | """ 65 | Form for creation user instances 66 | """ 67 | username = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Username'})) 68 | first_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'First Name'})) 69 | last_name = forms.CharField(required=True, widget=forms.widgets.TextInput(attrs={'placeholder': 'Last Name'})) 70 | password1 = forms.CharField(required=True, widget=forms.widgets.PasswordInput(attrs={'placeholder': 'Password'})) 71 | password2 = forms.CharField(required=True, 72 | widget=forms.widgets.PasswordInput(attrs={'placeholder': 'Password Confirmation'})) 73 | 74 | def is_valid(self): 75 | form = super(UserCreateForm, self).is_valid() 76 | for f, error in self.errors.iteritems(): 77 | if f != '__all_': 78 | self.fields[f].widget.attrs.update({'class': 'error', 'value': strip_tags(error)}) 79 | return form 80 | 81 | def save(self): 82 | user = super(UserCreateForm, self).save() 83 | user_profile = UserProfile(user=user, join_date=timezone.now()) 84 | user_profile.save() 85 | return user_profile 86 | 87 | class Meta: 88 | fields = ['username', 'first_name', 'last_name', 'password1', 89 | 'password2'] 90 | model = User 91 | 92 | 93 | class AuthenticateForm(AuthenticationForm): 94 | """ 95 | Form to authenticate user 96 | """ 97 | username = forms.CharField(widget=forms.widgets.TextInput(attrs={'placeholder': 'Username'})) 98 | password = forms.CharField(widget=forms.widgets.PasswordInput(attrs={'placeholder': 'Password'})) 99 | 100 | def is_valid(self): 101 | form = super(AuthenticateForm, self).is_valid() 102 | for f, error in self.errors.iteritems(): 103 | if f != '__all__': 104 | self.fields[f].widget.attrs.update({'class': 'error', 'value': strip_tags(error)}) 105 | return form 106 | 107 | 108 | class AuthorForm(ModelForm): 109 | """ 110 | ModelForm to create and edit Author. 111 | """ 112 | class Meta: 113 | model = Author 114 | fields = ['name', 'surname', 'date_of_birth', 'id'] 115 | widgets = { 116 | 'name': forms.widgets.TextInput(attrs={'placeholder': 'Name'}), 117 | 'surname': forms.widgets.TextInput(attrs={'placeholder': 'Surname'}), 118 | 'date_of_birth': forms.widgets.DateInput(attrs={'placeholder': 'Date of birth'}), 119 | 'id': forms.widgets.HiddenInput(), 120 | } 121 | 122 | 123 | class PublisherForm(ModelForm): 124 | """ 125 | ModelForm to create and edit Publisher. 126 | """ 127 | class Meta: 128 | model = Publisher 129 | fields = ['name'] 130 | widgets = { 131 | 'name': forms.widgets.TextInput(attrs={'placeholder': 'Name'}), 132 | } 133 | 134 | 135 | class LendPeriodForm(ModelForm): 136 | """ 137 | ModelForm to create and edit LendPeriod. 138 | """ 139 | class Meta: 140 | model = LendPeriods 141 | fields = ['name', 'days_amount'] 142 | widgets = { 143 | 'name': forms.widgets.TextInput(attrs={'placeholder': 'Name'}), 144 | 'days_amount': forms.widgets.TextInput(attrs={'placeholder': 'Amount of days'}), 145 | } 146 | 147 | 148 | class BookForm(ModelForm): 149 | """ 150 | ModelForm to create and edit Book. 151 | """ 152 | class Meta: 153 | model = Book 154 | fields = ['title', 'ISBN', 'publisher', 'author', 'lend_period', 'page_amount'] 155 | widgets = { 156 | 'title': forms.widgets.TextInput(attrs={'placeholder': 'Title'}), 157 | 'ISBN': forms.widgets.TextInput(attrs={'placeholder': 'ISBN'}), 158 | 'publisher': forms.widgets.Select(), 159 | 'author': forms.widgets.Select(attrs={'placeholder': 'Author'}), 160 | 'lend_period': forms.widgets.Select(attrs={'placeholder': 'Lend period'}), 161 | 'page_amount': forms.widgets.NumberInput(attrs={'min': 0, 'placeholder': 'Amount of pages'}), 162 | } 163 | -------------------------------------------------------------------------------- /library_app/helpers.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/helpers.py -------------------------------------------------------------------------------- /library_app/migrations/0001_initial.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='Author', 17 | fields=[ 18 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 19 | ('name', models.CharField(max_length=100)), 20 | ('surname', models.CharField(max_length=100)), 21 | ('date_of_birth', models.DateField()), 22 | ], 23 | options={ 24 | }, 25 | bases=(models.Model,), 26 | ), 27 | migrations.CreateModel( 28 | name='Book', 29 | fields=[ 30 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 31 | ('title', models.CharField(max_length=200)), 32 | ('ISBN', models.CharField(max_length=200)), 33 | ('page_amount', models.IntegerField()), 34 | ('lend_from', models.DateField()), 35 | ('author', models.ForeignKey(to='library_app.Author')), 36 | ], 37 | options={ 38 | }, 39 | bases=(models.Model,), 40 | ), 41 | migrations.CreateModel( 42 | name='LendPeriods', 43 | fields=[ 44 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 45 | ('name', models.CharField(max_length=50)), 46 | ('days_amount', models.IntegerField()), 47 | ], 48 | options={ 49 | }, 50 | bases=(models.Model,), 51 | ), 52 | migrations.CreateModel( 53 | name='Publisher', 54 | fields=[ 55 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 56 | ('name', models.CharField(max_length=100)), 57 | ], 58 | options={ 59 | }, 60 | bases=(models.Model,), 61 | ), 62 | migrations.CreateModel( 63 | name='UserProfile', 64 | fields=[ 65 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 66 | ('mobile', models.CharField(max_length=15)), 67 | ('website', models.CharField(max_length=50)), 68 | ('fb_name', models.CharField(max_length=60)), 69 | ('join_date', models.DateField()), 70 | ('friends', models.ManyToManyField(related_name='friends_rel_+', to='library_app.UserProfile')), 71 | ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), 72 | ], 73 | options={ 74 | }, 75 | bases=(models.Model,), 76 | ), 77 | migrations.AddField( 78 | model_name='book', 79 | name='lend_by', 80 | field=models.ForeignKey(to='library_app.UserProfile'), 81 | preserve_default=True, 82 | ), 83 | migrations.AddField( 84 | model_name='book', 85 | name='lend_period', 86 | field=models.ForeignKey(to='library_app.LendPeriods'), 87 | preserve_default=True, 88 | ), 89 | migrations.AddField( 90 | model_name='book', 91 | name='publisher', 92 | field=models.ForeignKey(to='library_app.Publisher'), 93 | preserve_default=True, 94 | ), 95 | ] 96 | -------------------------------------------------------------------------------- /library_app/migrations/0002_auto_20141218_1051.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('library_app', '0001_initial'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='userprofile', 16 | name='fb_name', 17 | field=models.CharField(max_length=60, null=True, blank=True), 18 | preserve_default=True, 19 | ), 20 | migrations.AlterField( 21 | model_name='userprofile', 22 | name='mobile', 23 | field=models.CharField(max_length=15, null=True, blank=True), 24 | preserve_default=True, 25 | ), 26 | migrations.AlterField( 27 | model_name='userprofile', 28 | name='website', 29 | field=models.CharField(max_length=50, null=True, blank=True), 30 | preserve_default=True, 31 | ), 32 | ] 33 | -------------------------------------------------------------------------------- /library_app/migrations/0003_auto_20141218_1200.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('library_app', '0002_auto_20141218_1051'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterModelOptions( 15 | name='author', 16 | options={'ordering': ['name', 'surname'], 'get_latest_by': 'name', 'verbose_name': 'Author', 'verbose_name_plural': 'Authors'}, 17 | ), 18 | migrations.AlterModelOptions( 19 | name='book', 20 | options={'ordering': ['title'], 'verbose_name': 'Book', 'verbose_name_plural': 'Books'}, 21 | ), 22 | migrations.AlterModelOptions( 23 | name='lendperiods', 24 | options={'ordering': ['days_amount'], 'get_latest_by': 'days_amount', 'verbose_name': 'Lending period', 'verbose_name_plural': 'Lending periods'}, 25 | ), 26 | migrations.AlterModelOptions( 27 | name='publisher', 28 | options={'ordering': ['name'], 'get_latest_by': 'name', 'verbose_name': 'Publisher', 'verbose_name_plural': 'Publishers'}, 29 | ), 30 | migrations.AlterModelOptions( 31 | name='userprofile', 32 | options={'ordering': ['user'], 'get_latest_by': 'join_date', 'verbose_name': 'User profile', 'verbose_name_plural': 'User profiles'}, 33 | ), 34 | migrations.AlterField( 35 | model_name='book', 36 | name='lend_by', 37 | field=models.ForeignKey(blank=True, to='library_app.UserProfile', null=True), 38 | preserve_default=True, 39 | ), 40 | migrations.AlterField( 41 | model_name='book', 42 | name='lend_from', 43 | field=models.DateField(null=True, blank=True), 44 | preserve_default=True, 45 | ), 46 | ] 47 | -------------------------------------------------------------------------------- /library_app/migrations/0004_quotationfrombook.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | from django.conf import settings 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | migrations.swappable_dependency(settings.AUTH_USER_MODEL), 12 | ('library_app', '0003_auto_20141218_1200'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='QuotationFromBook', 18 | fields=[ 19 | ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), 20 | ('quotation', models.CharField(max_length=600)), 21 | ('creation_date', models.DateField()), 22 | ('Book', models.ForeignKey(to='library_app.Book')), 23 | ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), 24 | ], 25 | options={ 26 | 'ordering': ['quotation'], 27 | 'get_latest_by': 'creation_date', 28 | 'verbose_name': 'Quotation', 29 | 'verbose_name_plural': 'Quotations', 30 | }, 31 | bases=(models.Model,), 32 | ), 33 | ] 34 | -------------------------------------------------------------------------------- /library_app/migrations/0005_auto_20141229_1907.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import models, migrations 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('library_app', '0004_quotationfrombook'), 11 | ] 12 | 13 | operations = [ 14 | migrations.RenameField( 15 | model_name='quotationfrombook', 16 | old_name='Book', 17 | new_name='book', 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /library_app/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/migrations/__init__.py -------------------------------------------------------------------------------- /library_app/models.py: -------------------------------------------------------------------------------- 1 | from django.db import models 2 | from django.contrib.auth.models import User 3 | import hashlib 4 | from django.utils import timezone 5 | 6 | 7 | class Book(models.Model): 8 | """ 9 | An Book class - to describe book in the system. 10 | """ 11 | title = models.CharField(max_length=200) 12 | ISBN = models.CharField(max_length=200) 13 | publisher = models.ForeignKey('Publisher') 14 | author = models.ForeignKey('Author') 15 | lend_period = models.ForeignKey('LendPeriods') 16 | page_amount = models.IntegerField() 17 | lend_by = models.ForeignKey('UserProfile', null=True, blank=True) 18 | lend_from = models.DateField(null=True, blank=True) 19 | 20 | def __unicode__(self): 21 | return 'Book: ' + self.title 22 | 23 | class Meta: 24 | ordering = ['title'] 25 | verbose_name = "Book" 26 | verbose_name_plural = "Books" 27 | 28 | 29 | class LendPeriods(models.Model): 30 | """ 31 | Users can borrow books from library for different 32 | time period. This class defines frequently-used 33 | lending periods. 34 | """ 35 | name = models.CharField(max_length=50) 36 | days_amount = models.IntegerField() 37 | 38 | def __unicode__(self): 39 | return '%s' % self.name 40 | 41 | class Meta: 42 | get_latest_by = "days_amount" 43 | ordering = ['days_amount'] 44 | verbose_name = "Lending period" 45 | verbose_name_plural = "Lending periods" 46 | 47 | 48 | class Publisher(models.Model): 49 | """ 50 | Class defines book's publisher 51 | """ 52 | name = models.CharField(max_length=100) 53 | 54 | def __unicode__(self): 55 | return 'Publisher: %s' % self.name 56 | 57 | class Meta: 58 | get_latest_by = "name" 59 | ordering = ['name'] 60 | verbose_name = "Publisher" 61 | verbose_name_plural = "Publishers" 62 | 63 | 64 | class Author(models.Model): 65 | """ 66 | Class defines book's author 67 | """ 68 | name = models.CharField(max_length=100) 69 | surname = models.CharField(max_length=100) 70 | date_of_birth = models.DateField() 71 | 72 | def __unicode__(self): 73 | return 'Author: ' + self.name + ' ' + self.surname 74 | 75 | def __str__(self): 76 | return 'Author: ' + self.name + ' ' + self.surname 77 | 78 | class Meta: 79 | get_latest_by = "name" 80 | ordering = ['name', 'surname'] 81 | verbose_name = "Author" 82 | verbose_name_plural = "Authors" 83 | 84 | 85 | class QuotationFromBook(models.Model): 86 | """ 87 | Class descirbes specific quotation from the book 88 | saved by specific user 89 | """ 90 | user = models.ForeignKey(User, blank=False, null=False) 91 | book = models.ForeignKey(Book, blank=False, null=False) 92 | quotation = models.CharField(max_length=600, null=False, blank=False) 93 | creation_date = models.DateField(blank=False, null=False) 94 | 95 | def __unicode__(self): 96 | return 'quotation: %s...' % self.quotation[0:12] 97 | 98 | def get_full_quotation(self): 99 | return '%s' % self.quotation 100 | 101 | class Meta: 102 | get_latest_by = "creation_date" 103 | ordering = ['quotation'] 104 | verbose_name = "Quotation" 105 | verbose_name_plural = "Quotations" 106 | 107 | 108 | class UserProfile(models.Model): 109 | """ 110 | Class provides more information according the system's users 111 | """ 112 | user = models.OneToOneField(User) 113 | mobile = models.CharField(max_length=15, null=True, blank=True) 114 | website = models.CharField(max_length=50, null=True, blank=True) 115 | fb_name = models.CharField(max_length=60, null=True, blank=True) 116 | friends = models.ManyToManyField('self', symmetrical=True) 117 | join_date = models.DateField() 118 | 119 | def __unicode__(self): 120 | return 'User profile: ' + self.user.username + ', ' + self.user.first_name + ' ' + self.user.last_name 121 | 122 | def gravator_url(self): 123 | return "http://www.gravatar.com/avatar/%s?s=50" % hashlib.md5(self.user.email).hexdigest() 124 | 125 | class Meta: 126 | get_latest_by = "join_date" 127 | ordering = ['user'] 128 | verbose_name = "User profile" 129 | verbose_name_plural = "User profiles" 130 | 131 | 132 | def get_or_create_userprofile(user): 133 | if user: 134 | # up = get_object_or_404(UserProfile, user=user) 135 | try: 136 | up = UserProfile.objects.get(user=user) 137 | if up: 138 | return up 139 | except ObjectDoesNotExist: 140 | pass 141 | up = UserProfile(user=user, join_date=timezone.now()) 142 | up.save() 143 | return up 144 | 145 | 146 | User.profile = property(lambda u: get_or_create_userprofile(user=u)) 147 | -------------------------------------------------------------------------------- /library_app/static/css/bootstrap-responsive.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Responsive v2.3.2 3 | * 4 | * Copyright 2013 Twitter, Inc 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Designed and built with all the love in the world by @mdo and @fat. 9 | */.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;line-height:0;content:""}.clearfix:after{clear:both}.hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden}.visible-phone{display:none!important}.visible-tablet{display:none!important}.hidden-desktop{display:none!important}.visible-desktop{display:inherit!important}@media(min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-tablet{display:inherit!important}.hidden-tablet{display:none!important}}@media(max-width:767px){.hidden-desktop{display:inherit!important}.visible-desktop{display:none!important}.visible-phone{display:inherit!important}.hidden-phone{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:inherit!important}.hidden-print{display:none!important}}@media(min-width:1200px){.row{margin-left:-30px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:30px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px}.span12{width:1170px}.span11{width:1070px}.span10{width:970px}.span9{width:870px}.span8{width:770px}.span7{width:670px}.span6{width:570px}.span5{width:470px}.span4{width:370px}.span3{width:270px}.span2{width:170px}.span1{width:70px}.offset12{margin-left:1230px}.offset11{margin-left:1130px}.offset10{margin-left:1030px}.offset9{margin-left:930px}.offset8{margin-left:830px}.offset7{margin-left:730px}.offset6{margin-left:630px}.offset5{margin-left:530px}.offset4{margin-left:430px}.offset3{margin-left:330px}.offset2{margin-left:230px}.offset1{margin-left:130px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%}.row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%}.row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%}.row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%}.row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%}.row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%}.row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%}.row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%}.row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%}.row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%}.row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%}.row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%}.row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%}.row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%}.row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%}.row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%}.row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%}.row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%}.row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%}.row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%}.row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%}.row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%}.row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%}.row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%}.row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%}.row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%}.row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%}.row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%}.row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%}.row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%}.row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%}.row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%}.row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%}.row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%}.row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:30px}input.span12,textarea.span12,.uneditable-input.span12{width:1156px}input.span11,textarea.span11,.uneditable-input.span11{width:1056px}input.span10,textarea.span10,.uneditable-input.span10{width:956px}input.span9,textarea.span9,.uneditable-input.span9{width:856px}input.span8,textarea.span8,.uneditable-input.span8{width:756px}input.span7,textarea.span7,.uneditable-input.span7{width:656px}input.span6,textarea.span6,.uneditable-input.span6{width:556px}input.span5,textarea.span5,.uneditable-input.span5{width:456px}input.span4,textarea.span4,.uneditable-input.span4{width:356px}input.span3,textarea.span3,.uneditable-input.span3{width:256px}input.span2,textarea.span2,.uneditable-input.span2{width:156px}input.span1,textarea.span1,.uneditable-input.span1{width:56px}.thumbnails{margin-left:-30px}.thumbnails>li{margin-left:30px}.row-fluid .thumbnails{margin-left:0}}@media(min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1}.row:before,.row:after{display:table;line-height:0;content:""}.row:after{clear:both}[class*="span"]{float:left;min-height:1px;margin-left:20px}.container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px}.span12{width:724px}.span11{width:662px}.span10{width:600px}.span9{width:538px}.span8{width:476px}.span7{width:414px}.span6{width:352px}.span5{width:290px}.span4{width:228px}.span3{width:166px}.span2{width:104px}.span1{width:42px}.offset12{margin-left:764px}.offset11{margin-left:702px}.offset10{margin-left:640px}.offset9{margin-left:578px}.offset8{margin-left:516px}.offset7{margin-left:454px}.offset6{margin-left:392px}.offset5{margin-left:330px}.offset4{margin-left:268px}.offset3{margin-left:206px}.offset2{margin-left:144px}.offset1{margin-left:82px}.row-fluid{width:100%;*zoom:1}.row-fluid:before,.row-fluid:after{display:table;line-height:0;content:""}.row-fluid:after{clear:both}.row-fluid [class*="span"]{display:block;float:left;width:100%;min-height:30px;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="span"]:first-child{margin-left:0}.row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%}.row-fluid .span12{width:100%;*width:99.94680851063829%}.row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%}.row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%}.row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%}.row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%}.row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%}.row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%}.row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%}.row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%}.row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%}.row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%}.row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%}.row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%}.row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%}.row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%}.row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%}.row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%}.row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%}.row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%}.row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%}.row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%}.row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%}.row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%}.row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%}.row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%}.row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%}.row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%}.row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%}.row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%}.row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%}.row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%}.row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%}.row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%}.row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%}.row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%}.row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%}input,textarea,.uneditable-input{margin-left:0}.controls-row [class*="span"]+[class*="span"]{margin-left:20px}input.span12,textarea.span12,.uneditable-input.span12{width:710px}input.span11,textarea.span11,.uneditable-input.span11{width:648px}input.span10,textarea.span10,.uneditable-input.span10{width:586px}input.span9,textarea.span9,.uneditable-input.span9{width:524px}input.span8,textarea.span8,.uneditable-input.span8{width:462px}input.span7,textarea.span7,.uneditable-input.span7{width:400px}input.span6,textarea.span6,.uneditable-input.span6{width:338px}input.span5,textarea.span5,.uneditable-input.span5{width:276px}input.span4,textarea.span4,.uneditable-input.span4{width:214px}input.span3,textarea.span3,.uneditable-input.span3{width:152px}input.span2,textarea.span2,.uneditable-input.span2{width:90px}input.span1,textarea.span1,.uneditable-input.span1{width:28px}}@media(max-width:767px){body{padding-right:20px;padding-left:20px}.navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-right:-20px;margin-left:-20px}.container-fluid{padding:0}.dl-horizontal dt{float:none;width:auto;clear:none;text-align:left}.dl-horizontal dd{margin-left:0}.container{width:auto}.row-fluid{width:100%}.row,.thumbnails{margin-left:0}.thumbnails>li{float:none;margin-left:0}[class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{display:block;float:none;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.row-fluid [class*="offset"]:first-child{margin-left:0}.input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto}.controls-row [class*="span"]+[class*="span"]{margin-left:0}.modal{position:fixed;top:20px;right:20px;left:20px;width:auto;margin:0}.modal.fade{top:-100px}.modal.fade.in{top:20px}}@media(max-width:480px){.nav-collapse{-webkit-transform:translate3d(0,0,0)}.page-header h1 small{display:block;line-height:20px}input[type="checkbox"],input[type="radio"]{border:1px solid #ccc}.form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left}.form-horizontal .controls{margin-left:0}.form-horizontal .control-list{padding-top:0}.form-horizontal .form-actions{padding-right:10px;padding-left:10px}.media .pull-left,.media .pull-right{display:block;float:none;margin-bottom:10px}.media-object{margin-right:0;margin-left:0}.modal{top:10px;right:10px;left:10px}.modal-header .close{padding:10px;margin:-10px}.carousel-caption{position:static}}@media(max-width:979px){body{padding-top:0}.navbar-fixed-top,.navbar-fixed-bottom{position:static}.navbar-fixed-top{margin-bottom:20px}.navbar-fixed-bottom{margin-top:20px}.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px}.navbar .container{width:auto;padding:0}.navbar .brand{padding-right:10px;padding-left:10px;margin:0 0 0 -5px}.nav-collapse{clear:both}.nav-collapse .nav{float:none;margin:0 0 10px}.nav-collapse .nav>li{float:none}.nav-collapse .nav>li>a{margin-bottom:2px}.nav-collapse .nav>.divider-vertical{display:none}.nav-collapse .nav .nav-header{color:#777;text-shadow:none}.nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nav-collapse .dropdown-menu li+li a{margin-bottom:2px}.nav-collapse .nav>li>a:hover,.nav-collapse .nav>li>a:focus,.nav-collapse .dropdown-menu a:hover,.nav-collapse .dropdown-menu a:focus{background-color:#f2f2f2}.navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999}.navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .nav>li>a:focus,.navbar-inverse .nav-collapse .dropdown-menu a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:focus{background-color:#111}.nav-collapse.in .btn-group{padding:0;margin-top:5px}.nav-collapse .dropdown-menu{position:static;top:auto;left:auto;display:none;float:none;max-width:none;padding:0;margin:0 15px;background-color:transparent;border:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.nav-collapse .open>.dropdown-menu{display:block}.nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none}.nav-collapse .dropdown-menu .divider{display:none}.nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none}.nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1)}.navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111;border-bottom-color:#111}.navbar .nav-collapse .nav.pull-right{float:none;margin-left:0}.nav-collapse,.nav-collapse.collapse{height:0;overflow:hidden}.navbar .btn-navbar{display:block}.navbar-static .navbar-inner{padding-right:10px;padding-left:10px}}@media(min-width:980px){.nav-collapse.collapse{height:auto!important;overflow:visible!important}} 10 | -------------------------------------------------------------------------------- /library_app/static/css/public_home.less: -------------------------------------------------------------------------------- 1 | body { 2 | background: white none; 3 | } 4 | 5 | .person-desc { 6 | text-align: justify; 7 | text-indent: 20px; 8 | } 9 | 10 | .lead { 11 | text-align: justify; 12 | text-indent: 40px; 13 | padding: 30px; 14 | } 15 | 16 | div.white-background, div.container, div.site-wrapper, div.content, 17 | div.site-wrapper-inner, div.cover-container { 18 | width: 100%; 19 | } 20 | 21 | div.flower { 22 | background-image: url(../img/flower.png); 23 | background-size: 70px 150px; 24 | width: 140px; 25 | height: 300px; 26 | position: absolute; 27 | // top: 0px; 28 | // left: 0px; 29 | margin-left: 20px; 30 | margin-top: 20px; 31 | z-index: 200; 32 | background-repeat: no-repeat; 33 | 34 | @media screen and (max-width: 1240px){ 35 | display: none; 36 | } 37 | } 38 | 39 | .img-responsive { 40 | margin-bottom: 30px; 41 | margin-top: 30px; 42 | } 43 | 44 | .navbar { 45 | background-color: #1a1a1a; 46 | } 47 | 48 | #first-feat { 49 | width: 70%; 50 | margin: 0 auto; 51 | border-radius: 50px; 52 | background: -webkit-linear-gradient(#9CBCD0, #9CBCDD); /* For Safari 5.1 to 6.0 */ 53 | background: -o-linear-gradient(#9CBCD0, #9CBCDD); /* For Opera 11.1 to 12.0 */ 54 | background: -moz-linear-gradient(#9CBCD0, #9CBCDD); /* For Firefox 3.6 to 15 */ 55 | background: linear-gradient(#9CBCD0, #9CBCDD); /* Standard syntax */ 56 | } 57 | 58 | #third-feat { 59 | width: 100%; 60 | background: -webkit-linear-gradient(#727272, #747592); /* For Safari 5.1 to 6.0 */ 61 | background: -o-linear-gradient(#727272, #747592); /* For Opera 11.1 to 12.0 */ 62 | background: -moz-linear-gradient(#727272, #747592); /* For Firefox 3.6 to 15 */ 63 | background: linear-gradient(#727272, #747592); /* Standard syntax */ 64 | } 65 | 66 | #third-feat { 67 | .featurette-heading, .lead { 68 | color: white; 69 | } 70 | } 71 | 72 | 73 | 74 | h1#team { 75 | padding-top: 25px; 76 | margin-top: 0px; 77 | } 78 | 79 | #content { 80 | width: 100%; 81 | } 82 | 83 | .container .marketing { 84 | width: 100%; 85 | } -------------------------------------------------------------------------------- /library_app/static/css/style.less: -------------------------------------------------------------------------------- 1 | .navbar-fixed-bottom { 2 | height: 40px; 3 | text-align: center; 4 | } 5 | 6 | div.footer-container-outer { 7 | display: table; 8 | position: absolute; 9 | height: 100%; 10 | width: 90%; 11 | } 12 | 13 | .navbar-inner { 14 | // width: 90%; 15 | margin: 0 auto; 16 | } 17 | 18 | .footer-container-outer { 19 | border-top-right-radius: 20px; 20 | border-top-left-radius: 20px; 21 | } 22 | 23 | div.footer-container { 24 | display: table-cell; 25 | vertical-align: middle; 26 | } 27 | 28 | div.footer-container-inner { 29 | color: white; 30 | margin-left: auto; 31 | margin-right: auto; 32 | width: 400px; 33 | } 34 | 35 | body { 36 | background-image: url("../img/cover.jpg"); 37 | padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */ 38 | } 39 | 40 | div.cover-container { 41 | width: 100% 42 | } 43 | 44 | div.logo { 45 | display: table-cell; 46 | margin-left: 0px; 47 | position: absolute; 48 | left: 0px; 49 | top: 0px; 50 | 51 | } 52 | 53 | img.logo_img { 54 | width: auto; 55 | height: 60px; 56 | } 57 | 58 | div.login { 59 | margin: auto; 60 | display: block; 61 | float: left; 62 | color: white; 63 | padding-top: 10px; 64 | padding-right: 20px; 65 | padding-left: 20px; 66 | } 67 | 68 | .log_form { 69 | margin: 0px; 70 | text-align: center; 71 | } 72 | 73 | .btn-text { 74 | color: white; 75 | } 76 | 77 | .btn-facebook { 78 | max-width: 240px; 79 | margin: auto; 80 | } 81 | 82 | div.panel { 83 | background-color : white; 84 | opacity: 0.9; 85 | margin: 15px; 86 | padding: 15px; 87 | border-radius: 15px; 88 | 89 | &.small { 90 | width: 40%; 91 | margin: auto; 92 | } 93 | 94 | &.medium { 95 | width: 85%; 96 | margin: auto; 97 | } 98 | 99 | &.main p { 100 | text-indent: 30px; 101 | } 102 | 103 | div.page-title-outer{ 104 | text-align: center; 105 | 106 | div.page-title { 107 | font-size: x-large; 108 | padding-bottom: 10px; 109 | } 110 | } 111 | } 112 | 113 | div.panel-outer { 114 | display: table; 115 | position: absolute; 116 | height: 90%; 117 | width: 100%; 118 | } 119 | 120 | div.panel-outside { 121 | display: table-cell; 122 | vertical-align: middle; 123 | } 124 | 125 | table.books_table { 126 | width: 100%; 127 | & td{ 128 | text-align: center; 129 | } 130 | } 131 | 132 | table.friends_table { 133 | width: 100%; 134 | } 135 | 136 | div.quote-from-friend { 137 | 138 | & div.gravator { 139 | margin-top:10px; 140 | } 141 | } 142 | 143 | div.quotation { 144 | padding-left: 10px; 145 | padding-right: 10px; 146 | padding-bottom: 10px; 147 | text-align: justify; 148 | } 149 | 150 | div.quote-from-friend { 151 | width : 250px; 152 | margin: auto; 153 | background-color: white; 154 | border-style: dashed; 155 | border-color: black; 156 | border-width: 2px; 157 | border-radius: 15px; 158 | float: right; 159 | 160 | & div.quotation-owner { 161 | text-align: center; 162 | } 163 | 164 | & div.quotation { 165 | text-indent: 10px; 166 | font-style: italic; 167 | } 168 | 169 | & div.gravator { 170 | width: 80px; 171 | & img { 172 | width: 80px; 173 | } 174 | } 175 | } 176 | 177 | .form-signin { 178 | max-width: 330px; 179 | padding: 15px; 180 | margin: 0 auto; 181 | } 182 | 183 | .form-signin .form-signin-heading, 184 | .form-signin .checkbox { 185 | margin-bottom: 10px; 186 | } 187 | 188 | .form-signin .checkbox { 189 | font-weight: normal; 190 | } 191 | 192 | .form-signin .form-control { 193 | position: relative; 194 | height: auto; 195 | -webkit-box-sizing: border-box; 196 | -moz-box-sizing: border-box; 197 | box-sizing: border-box; 198 | padding: 10px; 199 | font-size: 16px; 200 | } 201 | 202 | .form-signin .form-control:focus { 203 | z-index: 2; 204 | } 205 | 206 | .form-signin input[type="email"] { 207 | margin-bottom: -1px; 208 | border-bottom-right-radius: 0; 209 | border-bottom-left-radius: 0; 210 | } 211 | 212 | .form-signin input[type="password"] { 213 | margin-bottom: 10px; 214 | border-top-left-radius: 0; 215 | border-top-right-radius: 0; 216 | } 217 | 218 | span.blank { 219 | color: blue; 220 | } 221 | 222 | div.user_desc{ 223 | width: 180px; 224 | margin-left: auto; 225 | margin-right: auto; 226 | } 227 | 228 | div.book_desc{ 229 | width: 310px; 230 | margin-left: auto; 231 | margin-right: auto; 232 | } 233 | 234 | div.gravator { 235 | width: 51px; 236 | margin-left: auto; 237 | margin-right: auto; 238 | } 239 | 240 | .flash { 241 | padding: 10px; 242 | margin: 5px 20px 5px 20px; 243 | text-align: center; 244 | 245 | &.error { 246 | background: #ffefef; 247 | color: #4c1717; 248 | border: 1px solid #4c1717; 249 | } 250 | 251 | &.warning { 252 | background: #ffe4c1; 253 | color: #79420d; 254 | border: 1px solid #79420d; 255 | } 256 | 257 | &.success { 258 | background: #efffd7; 259 | color: #8ba015; 260 | border: 1px solid #8ba015; 261 | } 262 | 263 | &.info { 264 | background: #5097ff; 265 | color: #000000; 266 | border: 1px solid #8ba015; 267 | } 268 | 269 | &.debug { 270 | background: #62ff9f; 271 | font-style: italic; 272 | color: #a03342; 273 | border: 1px dashed #8ba015; 274 | } 275 | } 276 | 277 | span.quotation { 278 | color: green; 279 | font-weight: bolder; 280 | } 281 | 282 | span.deadline { 283 | color : red; 284 | } 285 | 286 | //CAROUSEL FROM BOOTSTRAP 287 | 288 | /* GLOBAL STYLES 289 | -------------------------------------------------- */ 290 | /* Padding below the footer and lighter body text */ 291 | 292 | body { 293 | padding-bottom: 40px; 294 | color: #5a5a5a; 295 | } 296 | 297 | /* CUSTOMIZE THE CAROUSEL 298 | -------------------------------------------------- */ 299 | 300 | /* Carousel base class */ 301 | .carousel { 302 | height: 500px; 303 | margin-bottom: 60px; 304 | margin-top: -20px; 305 | } 306 | /* Since positioning the image, we need to help out the caption */ 307 | .carousel-caption { 308 | z-index: 10; 309 | padding-left: 60px; 310 | padding-right: 60px; 311 | } 312 | 313 | /* Declare heights because of positioning of img element */ 314 | .carousel .item { 315 | height: 500px; 316 | background-color: #777; 317 | } 318 | .carousel-inner > .item > img { 319 | position: absolute; 320 | top: 0; 321 | left: 0; 322 | width: 100%; 323 | height: 500px; 324 | } 325 | 326 | #myCarousel { 327 | width: 90%; 328 | margin: 0 auto; 329 | } 330 | 331 | /* MARKETING CONTENT 332 | -------------------------------------------------- */ 333 | 334 | .marketing { 335 | text-align: center; 336 | 337 | & .col-lg-4 { 338 | margin-bottom: 20px; 339 | text-align: center; 340 | width: 250px; 341 | display: inline-block; 342 | 343 | & img.left { 344 | float: left; 345 | } 346 | } 347 | 348 | & .row{ 349 | text-align: center; 350 | } 351 | } 352 | 353 | 354 | /* Center align the text within the three columns below the carousel */ 355 | 356 | 357 | .marketing h2 { 358 | font-weight: normal; 359 | } 360 | 361 | .marketing .col-lg-4 p { 362 | margin-right: 10px; 363 | margin-left: 10px; 364 | } 365 | 366 | /* Featurettes 367 | ------------------------- */ 368 | 369 | .featurette-divider { 370 | margin: 80px 0; /* Space out the Bootstrap
more */ 371 | } 372 | 373 | /* Thin out the marketing headings */ 374 | .featurette-heading { 375 | font-weight: 300; 376 | line-height: 1; 377 | letter-spacing: -1px; 378 | } 379 | 380 | /* RESPONSIVE CSS 381 | -------------------------------------------------- */ 382 | 383 | @media (min-width: 768px) { 384 | /* Bump up size of carousel content */ 385 | 386 | .carousel-caption p { 387 | margin-bottom: 20px; 388 | font-size: 21px; 389 | line-height: 1.4; 390 | } 391 | 392 | .featurette-heading { 393 | font-size: 50px; 394 | } 395 | } 396 | 397 | @media (min-width: 992px) { 398 | 399 | .featurette-heading { 400 | margin-top: 120px; 401 | } 402 | } 403 | 404 | 405 | span.sr-only { 406 | visibility: hidden; 407 | } 408 | 409 | div.col-md-5 { 410 | display: inline-block; 411 | width: 300px; 412 | height: 300px; 413 | 414 | & img { 415 | vertical-align: bottom; 416 | } 417 | } 418 | 419 | div.col-md-7 { 420 | display: inline-block; 421 | width: 500px 422 | } 423 | 424 | div.fb_mess { 425 | font-size: 1.3em; 426 | } 427 | 428 | div.center { 429 | text-align: center; 430 | } 431 | 432 | span.red { 433 | color: red; 434 | } 435 | -------------------------------------------------------------------------------- /library_app/static/img/blank-face.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/blank-face.jpg -------------------------------------------------------------------------------- /library_app/static/img/c1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/c1.jpg -------------------------------------------------------------------------------- /library_app/static/img/c2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/c2.jpg -------------------------------------------------------------------------------- /library_app/static/img/c2_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/c2_cover.jpg -------------------------------------------------------------------------------- /library_app/static/img/c2_web_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/c2_web_banner.jpg -------------------------------------------------------------------------------- /library_app/static/img/c3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/c3.jpg -------------------------------------------------------------------------------- /library_app/static/img/c3_cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/c3_cover.jpg -------------------------------------------------------------------------------- /library_app/static/img/code.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/code.jpg -------------------------------------------------------------------------------- /library_app/static/img/cover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/cover.jpg -------------------------------------------------------------------------------- /library_app/static/img/face.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/face.jpg -------------------------------------------------------------------------------- /library_app/static/img/female-placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/female-placeholder.png -------------------------------------------------------------------------------- /library_app/static/img/flower.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/flower.png -------------------------------------------------------------------------------- /library_app/static/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /library_app/static/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /library_app/static/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/logo.png -------------------------------------------------------------------------------- /library_app/static/img/logo_big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/logo_big.png -------------------------------------------------------------------------------- /library_app/static/img/logo_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/logo_small.png -------------------------------------------------------------------------------- /library_app/static/img/palm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/palm.jpg -------------------------------------------------------------------------------- /library_app/static/img/road.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/static/img/road.jpg -------------------------------------------------------------------------------- /library_app/static/js/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by potan on 27.12.14. 3 | */ 4 | 5 | var animation_time = 3000; 6 | 7 | function hide_elements(){ 8 | if (typeof $('.hidden') != 'undefined'){ 9 | $('.hidden').fadeOut(1, function(){}); 10 | } 11 | } 12 | 13 | function appear_quote(nr){ 14 | if (typeof $("#q"+nr) != 'undefined'){ 15 | $("#q"+nr).fadeIn(animation_time, function(){}); 16 | } 17 | } 18 | 19 | function disappear_quote(nr){ 20 | if (typeof $("#q"+nr) != 'undefined'){ 21 | $("#q"+nr).fadeOut(animation_time, function(){}); 22 | } 23 | } 24 | 25 | function animate_quote(nr, count){ 26 | appear_quote(nr); 27 | disappear_quote(nr); 28 | setTimeout(function () { 29 | var next = (nr + 1) > count ? 0 : (nr+1) 30 | animate_quote(next, count); 31 | }, 2 * animation_time); 32 | } 33 | 34 | function animate(){ 35 | var count = $('#count-div').attr('count'); 36 | var actual_nr = 0; 37 | 38 | if (typeof count != 'undefined'){ 39 | if (count > 0) { 40 | animate_quote(0, count); 41 | } 42 | } 43 | } 44 | 45 | $(document).ready(function(){ 46 | if (typeof $(".flash") != 'undefined'){ 47 | $(".flash").fadeOut(25000, function(){}); 48 | } 49 | 50 | hide_elements(); 51 | animate(); 52 | }); 53 | 54 | 55 | -------------------------------------------------------------------------------- /library_app/tables.py: -------------------------------------------------------------------------------- 1 | import django_tables2 as tables 2 | from .models import Book, UserProfile, Author, Publisher, LendPeriods 3 | from datetime import timedelta, date 4 | 5 | 6 | class PeriodsTable(tables.Table): 7 | """ 8 | Table to render LendingPeriods from database 9 | """ 10 | def render_name(self, record): 11 | return '%s' % (record.id, record.name) 12 | 13 | class Meta: 14 | model = LendPeriods 15 | attrs = {'class': 'books_table'} 16 | sequence = ('name', 'days_amount') 17 | fields = ('name', 'days_amount') 18 | 19 | 20 | class PublisherTable(tables.Table): 21 | """ 22 | Table to render Publishers from database 23 | """ 24 | def render_name(self, record): 25 | return '%s' % (record.id, record.name) 26 | 27 | class Meta: 28 | model = Publisher 29 | attrs = {'class': 'books_table'} 30 | sequence = ('name',) 31 | fields = ('name',) 32 | 33 | 34 | class AuthorTable(tables.Table): 35 | """ 36 | Table to render Authors from databes 37 | """ 38 | def render_name(self, record): 39 | return '%s' % (record.id, record.name) 40 | 41 | class Meta: 42 | model = Author 43 | attrs = {'class': 'books_table'} 44 | sequence = ('name', 'surname', 'date_of_birth') 45 | fields = ('name', 'surname', 'date_of_birth') 46 | 47 | 48 | class BookTable(tables.Table): 49 | """ 50 | Table to render Books from database 51 | """ 52 | publisher = tables.Column() 53 | 54 | lend_period = tables.Column(verbose_name="Borrow for") 55 | 56 | def render_title(self, record): 57 | return '%s' % (record.id, record.title) 58 | 59 | def render_publisher(self, value): 60 | return '%s' % (value.__unicode__())[11:] 61 | 62 | 63 | def render_author(self, value): 64 | return '%s' % (value.__unicode__())[8:] 65 | 66 | def render_lend_period(self, record): 67 | if record.lend_by != None: 68 | return 'Already lent' 69 | else: 70 | return "%s" % (record.id, record.title, record.lend_period, record.lend_period.__unicode__()) 71 | 72 | class Meta: 73 | model = Book 74 | attrs = {'class': 'books_table'} 75 | sequence = ('title', 'author', 'publisher', 'page_amount', 'lend_period') 76 | fields = ('title', 'author', 'publisher', 'page_amount', 'lend_period') 77 | 78 | 79 | class BookTableUser(BookTable): 80 | """ 81 | This table renders books, but is used to present 82 | books borrowed by the user and thus slightly differs from BookTable 83 | """ 84 | lend_period = tables.Column(verbose_name="Need to return in") 85 | 86 | def render_lend_period(self, record): 87 | tekst = (record.lend_from + timedelta(days=record.lend_period.days_amount) - date.today()).__str__()[0:-9] 88 | if int(tekst[0:-5]) > 0: 89 | return '%s' % (record.lend_from + timedelta(days=record.lend_period.days_amount) - date.today()).__str__()[0:-9] 90 | else: 91 | return 'After the deadline!' 92 | 93 | class Meta: 94 | model = Book 95 | attrs = {'class': 'books_table'} 96 | sequence = ('title', 'author', 'publisher', 'page_amount', 'lend_period') 97 | fields = ('title', 'author', 'publisher', 'page_amount', 'lend_period') 98 | 99 | 100 | class FriendTable(tables.Table): 101 | """ 102 | Table presents user's friend 103 | """ 104 | gravator = tables.Column(accessor='gravator_url') 105 | first_name = tables.Column(accessor='user.first_name') 106 | last_name = tables.Column(accessor='user.last_name') 107 | facebook = tables.Column(accessor='fb_name') 108 | 109 | def render_gravator(self, record): 110 | return '' % (record.user.username, 111 | record.user.profile.gravator_url()) 112 | 113 | def render_facebook(self, record): 114 | if record.user.profile.fb_name: 115 | return '%s' % (record.user.profile.fb_name, record.user.profile.fb_name) 116 | else: 117 | return '-<Blank>-' 118 | 119 | class Meta: 120 | model = UserProfile 121 | attrs = {'class': 'books_table'} 122 | fields = ('gravator', 'user', 'first_name', 'last_name', 'facebook') 123 | sequence = ('gravator', 'user', 'first_name', 'last_name', 'facebook') 124 | -------------------------------------------------------------------------------- /library_app/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/srik1040/django-library/2c914b0915865be3d3c08dbb0a0b4e96270a52e3/library_app/templatetags/__init__.py -------------------------------------------------------------------------------- /library_app/templatetags/has_group.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.contrib.auth.models import Group 3 | 4 | 5 | register = template.Library() 6 | 7 | 8 | @register.filter(name='has_group') 9 | def has_group(user, group_name): 10 | """ 11 | Checks if user belongs to certain group 12 | """ 13 | group = Group.objects.get(name=group_name) 14 | return True if group in user.groups.all() else False 15 | 16 | 17 | # register.filter('has_group', has_group) 18 | -------------------------------------------------------------------------------- /library_app/templatetags/render_object.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.template.loader import render_to_string 3 | from django.db.models import Model 4 | from django.utils.safestring import mark_safe 5 | 6 | register = template.Library() 7 | BASE_PATH = 'render' 8 | 9 | 10 | class RenderObjectNode(template.Node): 11 | def __init__(self, object_ref, position, varname): 12 | self.object_ref = template.Variable(object_ref) 13 | if position and position[0] in ('\'', '\"') and position[0] == position[-1]: 14 | position = position[1:-1] 15 | self.position = position 16 | self.varname = varname 17 | 18 | def render(self, context): 19 | # Retrieve the object from the template context 20 | try: 21 | object_ref = self.object_ref.resolve(context) 22 | assert isinstance(object_ref, Model) 23 | except (template.VariableDoesNotExist, AssertionError): 24 | # No context variable found, or variable was not a model 25 | model_name = None 26 | else: 27 | model_name = object_ref._meta.app_label + '_' + object_ref._meta.module_name 28 | 29 | # Construct the template loader list 30 | templates = [] 31 | if self.position: 32 | if model_name: 33 | templates += ['%s/%s/%s.html' % (BASE_PATH, self.position, model_name)] 34 | templates += ['%s/%s/default.html' % (BASE_PATH, self.position)] 35 | if model_name: 36 | templates += ['%s/%s.html' % (BASE_PATH, model_name)] 37 | templates += ['%s/default.html' % BASE_PATH] 38 | 39 | # Render the object and output it or add it to the template context 40 | try: 41 | rendered = render_to_string(templates, {'object': object_ref}, context) 42 | except template.TemplateDoesNotExist: 43 | # No template found -- fail silently 44 | if self.varname: 45 | context[self.varname] = '' 46 | return '' 47 | rendered = mark_safe(rendered) 48 | if self.varname: 49 | context[self.varname] = rendered 50 | return '' 51 | else: 52 | return rendered 53 | 54 | def do_render_object(parser, token): 55 | """ 56 | Used to output a rendered representation of a given model object. 57 | 58 | This tag allows you to use standard templates to describe how you want a given 59 | model to be displayed. Once you have created a rendering template for a model, 60 | you can simply feed it to the ``render_object`` tag and it will know how to 61 | output it in your template. 62 | 63 | This is generally useful when you need to render a list of objects of many 64 | types, or when you need to display an object but don't know ahead of time what 65 | type it is. For example, if your site search returns a list of objects from 66 | various models, you can simply loop over them and use ``render_object``. 67 | 68 | Usage:: 69 | 70 | {% render_object [object] for "[position]" as [varname] %} 71 | 72 | The ``object`` argument should be a reference to the actual object to be 73 | rendered. The remaining arguments (described below) are all optional. 74 | 75 | By default, the tag will attempt to render the ``object`` by choosing the first 76 | template from the following locations:: 77 | 78 | "render/[app_label]_[model_name].html" 79 | "render/default.html" 80 | 81 | If no template is found, the tag will output an empty string. When a template 82 | is found, it will receive the same context as the original template, plus an 83 | ``object`` variable which holds the model object. 84 | 85 | If you specify ``for "[position]"``, you can give a single model different 86 | representations for different locations throughout your site. If you include a 87 | ``position`` argument, ``render_object`` will add a couple templates to the top 88 | of the list, like so:: 89 | 90 | "render/[position]/[app_label]_[model_name].html" 91 | "render/[position]/default.html" 92 | "render/[app_label]_[model_name].html" 93 | "render/default.html" 94 | 95 | If you specify ``as [varname]``, the tag will place the rendered text into a 96 | context variable instead of outputting it to the template. 97 | """ 98 | bits = token.split_contents() 99 | varname = None 100 | position = None 101 | if bits[-2] == 'as': 102 | # Get the varname, if specified 103 | varname = bits[-1] 104 | bits = bits[:-2] 105 | if bits[-2] == 'for': 106 | # Get the position, if specified 107 | position = bits[-1] 108 | bits = bits[:-2] 109 | if len(bits) != 2: 110 | raise template.TemplateSyntaxError("%r tag has two required arguments" % bits[0]) 111 | return RenderObjectNode(bits[1], position, varname) 112 | 113 | register.tag('render_object', do_render_object) -------------------------------------------------------------------------------- /library_app/templatetags/xextends.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | from django.template.loader_tags import do_extends 3 | import tokenize 4 | import StringIO 5 | 6 | register = template.Library() 7 | 8 | class XExtendsNode(template.Node): 9 | def __init__(self, node, kwargs): 10 | self.node = node 11 | self.kwargs = kwargs 12 | 13 | def render(self, context): 14 | # TODO: add the values to the bottom of the context stack instead? 15 | context.update(self.kwargs) 16 | try: 17 | return self.node.render(context) 18 | finally: 19 | context.pop() 20 | 21 | def do_xextends(parser, token): 22 | """ 23 | Allows to extend specific template, but additionally 24 | pass certain parameters to it. 25 | """ 26 | bits = token.contents.split() 27 | kwargs = {} 28 | if 'with' in bits: 29 | pos = bits.index('with') 30 | argslist = bits[pos+1:] 31 | bits = bits[:pos] 32 | for i in argslist: 33 | try: 34 | a, b = i.split('=', 1); a = a.strip(); b = b.strip() 35 | keys = list(tokenize.generate_tokens(StringIO.StringIO(a).readline)) 36 | if keys[0][0] == tokenize.NAME: 37 | kwargs[str(a)] = parser.compile_filter(b) 38 | else: raise ValueError 39 | except ValueError: 40 | raise template.TemplateSyntaxError, "Argument syntax wrong: should be key=value" 41 | # before we are done, remove the argument part from the token contents, 42 | # or django's extends tag won't be able to handle it. 43 | # TODO: find a better solution that preserves the orginal token including whitespace etc. 44 | token.contents = " ".join(bits) 45 | 46 | # let the orginal do_extends parse the tag, and wrap the ExtendsNode 47 | return XExtendsNode(do_extends(parser, token), kwargs) 48 | 49 | register.tag('xextends', do_xextends) -------------------------------------------------------------------------------- /library_app/tests.py: -------------------------------------------------------------------------------- 1 | from django.test import TestCase 2 | from .models import Book, Author, Publisher, LendPeriods 3 | from django.utils import timezone 4 | from django.test import Client 5 | import unittest 6 | from django.test import LiveServerTestCase 7 | from selenium import webdriver 8 | from selenium.webdriver.common.keys import Keys 9 | from datetime import datetime 10 | 11 | 12 | class SimpleDataTests(TestCase): 13 | """ 14 | Performs simple database tests e.g., if certain models (Author, 15 | Publisher, LendingPeriod, Book) can be correctly instantiated 16 | """ 17 | def test_author(self): 18 | self.assertEqual(Author.objects.all().count(), 0) 19 | self.author1 = Author.objects.create(name="Imie", surname="Nazwisko", date_of_birth=timezone.now()) 20 | self.assertEqual(Author.objects.all().count(), 1) 21 | self.assertEqual(Author.objects.filter(name__exact="Imie").count(), 1) 22 | 23 | def test_publisher(self): 24 | self.assertEqual(Publisher.objects.all().count(), 0) 25 | self.publisher1 = Publisher.objects.create(name="Nazwa wydawnictwa") 26 | self.assertEqual(Publisher.objects.all().count(), 1) 27 | self.assertEqual(Publisher.objects.filter(name__exact="Nazwa wydawnictwa").count(), 1) 28 | 29 | def test_period(self): 30 | self.assertEqual(LendPeriods.objects.all().count(), 0) 31 | self.period1 = LendPeriods.objects.create(name="month", days_amount=31) 32 | self.assertEqual(LendPeriods.objects.all().count(), 1) 33 | self.assertEqual(LendPeriods.objects.filter(days_amount__exact=31).count(), 1) 34 | 35 | def test_book(self): 36 | self.assertEqual(Book.objects.all().count(), 0) 37 | self.author1 = Author.objects.create(name="Imie", surname="Nazwisko", date_of_birth=timezone.now()) 38 | self.publisher1 = Publisher.objects.create(name="Nazwa wydawnictwa") 39 | self.period1 = LendPeriods.objects.create(name="month", days_amount=31) 40 | 41 | self.book1 = Book.objects.create(title="Tytul", ISBN="9232", 42 | publisher=self.publisher1, 43 | author=self.author1, 44 | lend_period=self.period1, 45 | page_amount=360) 46 | 47 | self.assertEqual(Book.objects.all().count(), 1) 48 | self.assertEqual(Book.objects.filter(title__exact="Tytul").count(), 1) 49 | 50 | 51 | class SimpleWebTest(TestCase): 52 | """ 53 | Tests if specific urls (about, home, sign in/up) exist and contains 54 | necessary phrases 55 | """ 56 | def setUp(self): 57 | self.client = Client() 58 | 59 | def test_about(self): 60 | response = self.client.get('/about/') 61 | self.assertEqual(response.status_code, 200) 62 | self.assertTemplateUsed(response, 'about.html') 63 | self.assertContains(response, 'About us') 64 | 65 | def test_home(self): 66 | response = self.client.get('/') 67 | self.assertEqual(response.status_code, 200) 68 | self.assertTemplateUsed(response, 'public_home.html') 69 | self.assertContains(response, 'Welcome in Library Online Management System') 70 | 71 | def test_sign_in(self): 72 | response = self.client.get('/sign_in/') 73 | self.assertEqual(response.status_code, 200) 74 | self.assertTemplateUsed(response, 'sign_in.html') 75 | self.assertContains(response, 'Please sign in') 76 | 77 | def test_sign_up(self): 78 | response = self.client.get('/sign_up/') 79 | self.assertEqual(response.status_code, 200) 80 | self.assertTemplateUsed(response, 'sign_up.html') 81 | self.assertContains(response, 'Please sign up') 82 | self.assertContains(response, 'Sign up with FB') 83 | 84 | 85 | class PagesForAuthorizedUserAreBlocked(unittest.TestCase): 86 | """ 87 | Checks if pages restricted to authorized users can not 88 | be accessible by unauthorized ones. 89 | """ 90 | def setUp(self): 91 | self.client = Client() 92 | 93 | def test_books(self): 94 | response = self.client.get('/books/') 95 | self.assertEqual(response.status_code, 302) 96 | 97 | def test_authors(self): 98 | response = self.client.get('/authors/') 99 | self.assertEqual(response.status_code, 302) 100 | 101 | def test_periods(self): 102 | response = self.client.get('/periods/') 103 | self.assertEqual(response.status_code, 302) 104 | 105 | def test_quotations(self): 106 | response = self.client.get('/my_quotations') 107 | self.assertEqual(response.status_code, 301) 108 | 109 | # pages for librarians 110 | 111 | def test_adding_book(self): 112 | response = self.client.get('/books/new') 113 | self.assertEqual(response.status_code, 301) 114 | 115 | def test_adding_publisher(self): 116 | response = self.client.get('/publishers/new') 117 | self.assertEqual(response.status_code, 301) 118 | 119 | def test_adding_period(self): 120 | response = self.client.get('/periods/new') 121 | self.assertEqual(response.status_code, 301) 122 | 123 | def test_adding_author(self): 124 | response = self.client.get('/authors/new') 125 | self.assertEqual(response.status_code, 301) 126 | 127 | def test_editing_book(self): 128 | response = self.client.get('/books/edit/1') 129 | self.assertEqual(response.status_code, 302) 130 | 131 | def test_editing_publisher(self): 132 | response = self.client.get('/publishers/edit/1') 133 | self.assertEqual(response.status_code, 302) 134 | 135 | def test_editing_period(self): 136 | response = self.client.get('/periods/edit/1') 137 | self.assertEqual(response.status_code, 302) 138 | 139 | def test_editing_author(self): 140 | response = self.client.get('/authors/edit/1') 141 | self.assertEqual(response.status_code, 302) 142 | 143 | 144 | class AdminPanelTest(LiveServerTestCase): 145 | """ 146 | Simple selenium test. In this case we are adding an Author instance 147 | in django admin (which is, obviously, not necessarily 148 | what we usually want to test, but this demonstrates 149 | ability to use selenium for testing purposes). 150 | """ 151 | fixtures = ['users.json'] 152 | 153 | def setUp(self): 154 | self.browser = webdriver.Firefox() 155 | self.browser.implicitly_wait(3) 156 | 157 | def tearDown(self): 158 | self.browser.quit() 159 | 160 | def test_can_create_new_authors_via_admin_site(self): 161 | # Gertrude opens her web browser, and goes to the admin page 162 | self.browser.get(self.live_server_url + '/admin/') 163 | 164 | body = self.browser.find_element_by_tag_name('body') 165 | self.assertIn('Django administration', body.text) 166 | 167 | username_field = self.browser.find_element_by_name('username') 168 | username_field.send_keys('potan') 169 | 170 | password_field = self.browser.find_element_by_name('password') 171 | password_field.send_keys('12345') 172 | password_field.send_keys(Keys.RETURN) 173 | 174 | body = self.browser.find_element_by_tag_name('body') 175 | self.assertIn('Site administration', body.text) 176 | self.assertIn('Authors', body.text) 177 | 178 | new_author_link = self.browser.find_element_by_link_text('Authors') 179 | new_author_link.click() 180 | 181 | new_author_link = self.browser.find_element_by_link_text('Add Author') 182 | new_author_link.click() 183 | 184 | body = self.browser.find_element_by_tag_name('body') 185 | self.assertIn('Name:', body.text) 186 | self.assertIn('Surname:', body.text) 187 | self.assertIn('Date of birth:', body.text) 188 | 189 | field = self.browser.find_element_by_name('name') 190 | field.send_keys("Piotr") 191 | field = self.browser.find_element_by_name('surname') 192 | field.send_keys("Gasowski") 193 | field = self.browser.find_element_by_name('date_of_birth') 194 | 195 | now = datetime.now() 196 | date = "%d-%d-%d" % (now.year, now.month, now.day) 197 | field.send_keys(date) 198 | 199 | # self.browser.find_elements_by_link_text("Today").click() 200 | 201 | save_button = self.browser.find_element_by_css_selector("input[value='Save']") 202 | save_button.click() 203 | 204 | links = self.browser.find_elements_by_link_text( 205 | "Author: Piotr Gasowski" 206 | ) 207 | self.assertEquals(len(links), 1) 208 | -------------------------------------------------------------------------------- /library_app/validators.py: -------------------------------------------------------------------------------- 1 | from django.core.exceptions import ValidationError 2 | from .models import UserProfile, User 3 | 4 | def email_vailidator(email): 5 | pass -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == "__main__": 6 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "library.settings") 7 | 8 | from django.core.management import execute_from_command_line 9 | 10 | execute_from_command_line(sys.argv) 11 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django==1.7.1 2 | dj-database-url==0.3.0 3 | gunicorn==19.1.1 4 | psycopg2==2.5.4 5 | facepy==1.0.4 6 | fandjango==4.2 7 | django-tables2==0.15.0 8 | django-json-field==0.5.7 9 | django-jsonfield==0.9.13 10 | --------------------------------------------------------------------------------