=== removed file 'COPYING.AGPL-3'
--- COPYING.AGPL-3	2010-09-22 08:51:55 +0000
+++ COPYING.AGPL-3	1970-01-01 00:00:00 +0000
@@ -1,661 +0,0 @@
-                    GNU AFFERO GENERAL PUBLIC LICENSE
-                       Version 3, 19 November 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU Affero General Public License is a free, copyleft license for
-software and other kinds of works, specifically designed to ensure
-cooperation with the community in the case of network server software.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-our General Public Licenses are intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  Developers that use our General Public Licenses protect your rights
-with two steps: (1) assert copyright on the software, and (2) offer
-you this License which gives you legal permission to copy, distribute
-and/or modify the software.
-
-  A secondary benefit of defending all users' freedom is that
-improvements made in alternate versions of the program, if they
-receive widespread use, become available for other developers to
-incorporate.  Many developers of free software are heartened and
-encouraged by the resulting cooperation.  However, in the case of
-software used on network servers, this result may fail to come about.
-The GNU General Public License permits making a modified version and
-letting the public access it on a server without ever releasing its
-source code to the public.
-
-  The GNU Affero General Public License is designed specifically to
-ensure that, in such cases, the modified source code becomes available
-to the community.  It requires the operator of a network server to
-provide the source code of the modified version running there to the
-users of that server.  Therefore, public use of a modified version, on
-a publicly accessible server, gives the public access to the source
-code of the modified version.
-
-  An older license, called the Affero General Public License and
-published by Affero, was designed to accomplish similar goals.  This is
-a different license, not a version of the Affero GPL, but Affero has
-released a new version of the Affero GPL which permits relicensing under
-this license.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU Affero General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Remote Network Interaction; Use with the GNU General Public License.
-
-  Notwithstanding any other provision of this License, if you modify the
-Program, your modified version must prominently offer all users
-interacting with it remotely through a computer network (if your version
-supports such interaction) an opportunity to receive the Corresponding
-Source of your version by providing access to the Corresponding Source
-from a network server at no charge, through some standard or customary
-means of facilitating copying of software.  This Corresponding Source
-shall include the Corresponding Source for any work covered by version 3
-of the GNU General Public License that is incorporated pursuant to the
-following paragraph.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the work with which it is combined will remain governed by version
-3 of the GNU General Public License.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU Affero General Public License from time to time.  Such new versions
-will be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU Affero General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU Affero General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU Affero General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU Affero General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU Affero General Public License for more details.
-
-    You should have received a copy of the GNU Affero General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If your software can interact with users remotely through a computer
-network, you should also make sure that it provides a way for users to
-get its source.  For example, if your program is a web application, its
-interface could display a "Source" link that leads users to an archive
-of the code.  There are many ways you could offer source, and different
-solutions will be better for different programs; see section 13 for the
-specific requirements.
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU AGPL, see
-<http://www.gnu.org/licenses/>.

=== removed file 'HACKING'
--- HACKING	2010-12-20 10:59:50 +0000
+++ HACKING	1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-To get the development (nonstable) code and start hacking on it:
-
-$ bzr get lp:launch-control
-$ cd launch-control
-$ ./setup-dev-env.sh
-$ ./dashboard_server/manage.py runserver &
-$ xdg-open http://localhost:8000/
-
-You will need to have some dependencies installed and some stuff from infrastructure snapshots ppa:
-
-$ sudo add-apt-repositroy ppa:linaro-infrastructure/launch-control-snapshots
-$ sudo apt-get update
-$ sudo apt-get install launch-control-tool python-django python-django-openid-auth python-docutils python-linaro-json python-django-testscenarios

=== removed file 'INSTALL'
--- INSTALL	2010-09-30 08:46:06 +0000
+++ INSTALL	1970-01-01 00:00:00 +0000
@@ -1,76 +0,0 @@
-Installation
-============
-
-There are two possible options for installation right now:
-
-1) Run directly from the checkout (development and evaluation)
-2) Install in /opt + /srv and configure to run via apache (production)
-
-The first option is attractive to anyone who just wants to try it out without
-any hassle. The second option should be used if you plan on having a
-continuous service.
-
-
-Running directly from a checkout
-================================
-
-There is very little you have to do, assuming you already have a checkout (if
-you are reading this online and have bazaar installed you can get the latest
-stable source directly from trunk with `bzr get lp:launch-control') you only
-need to make sure you have required dependencies (see README) 
-
-From within the source tree issue the following commands:
-1) ./dashboard_server/manage.py syncdb
-2) ./dashboard_server/manage.py runserver
-
-Then open your favourite browser and point it at http://localhost:8000/
-
-
-Installation in /opt + /srv
-===========================
-
-The following script is suitable for installation in /opt (code & settings)
-and /srv (data).  Tthe script is meant to be read and executed manually, you
-need to interact with some steps
-
-# Setup space for code and data and fetch latest tree
-sudo mkdir -p /opt/dashboard/
-sudo mkdir -p /srv/dashboard/media
-sudo chown www-data.www-data /srv/dashboard/
-sudo bzr get lp:launch-control/0.1 /opt/dashboard/stable
-
-# Configure web server and dashboard for production deployment
-sudo cp /opt/dashboard/stable/dashboard_server/local_settings.py.example /opt/dashboard/stable/dashboard_server/local_settings.py
-# Things to do here:
-# 1) specify system administrators
-# 2) set SECRET_KEY to a random string
-# 3) configure database settings (optional)
-# 4) confirm installation and data paths (optional)
-sudo $EDITOR /opt/dashboard/stable/dashboard_server/local_settings.py
-# Note: here the system will interact with your database, if you configured
-# something else than the default (sqlite) you must ensure that appropriate
-# permissions are granted in advance.
-# Note: if this is your first installation you will be prompted to create an
-# administrator account. You should do so now. If you miss this step somehow
-# you can issue 'createsuperuser' (instead of syncdb) command later. 
-sudo -u www-data /opt/dashboard/stable/dashboard_server/manage.py syncdb
-
-# Tweak to your preference, default is to have a *:80/dashboard/ virtual host
-# Most likely you will want to change this, note that you _MUST_
-# change local_settings.py if you want to choose another location for
-# the dashboard (eg http://hostname/ vs http://hostname/dashboard/)
-sudo cp /opt/dashboard/stable/dashboard_server/apache.conf /etc/apache2/sites-available/dashboard
-sudo $EDITOR /etc/apache2/sites-available/dashboard
-
-# Enable dashboard app and restart apache
-sudo a2ensite dashboard
-sudo service apache restart
-
-
-First run
-=========
-
-Now go to http://your-site/dashboard/admin and sign-in with the username and
-password you provided at syncdb or createsuperuser step. Before the system can
-be used you must create an anonymous bundle stream. You can do this by
-selecting "Bundle Streams" "Add" and "Save" from the admin panel.

=== removed file 'MANIFEST.in'
--- MANIFEST.in	2012-12-09 21:23:10 +0000
+++ MANIFEST.in	1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
-include COPYING.AGPL-3 
-include HACKING
-include INSTALL 
-include NEWS 
-include README 
-include setup-dev-env.sh
-recursive-include dashboard_app/fixtures *.json
-recursive-include dashboard_app/templates *.html *.txt
-recursive-include dashboard_app/tests/regressions *.json
-recursive-include dashboard_app/static *.png *.js *.css
-recursive-include dashboard_app/templates *.html
-recursive-include examples *.xml *.json *html

=== removed file 'NEWS'
--- NEWS	2011-05-03 20:20:30 +0000
+++ NEWS	1970-01-01 00:00:00 +0000
@@ -1,119 +0,0 @@
-Release 0.4:
-
-Improvements to application core:
- * Old reporting framework has been removed and replaced with new approach.
-   Old data sources have become data views, pure SQL-based construct. Old
-   reports have been converted from python applications to client-side
-   JavaScript snippets that can query data views via XML-RPC. Both reports and
-   data views are loaded from .xml files from configurable directories.
- * Database schema is now managed by South, custom migrations are now possible
-   without dropping the database.
- * Data security (a feature where uploaded content could be private) has been
-   removed due to complexity with providing security with anonymous SQL
-   queries.
- * A number of XML-RPC methods has been added to implement data views.
-
-Improvements to user interface:
- * The jQuery UI theme has been changed form smoothness to Aristo. This theme
-   is much more pleasant looking. 
-
-Other changes:
- * Initial release of jQuery API for Dashboard.
-
-Release 0.3:
-
-Improvements to test code:
- * Tests are now separated to topic-driven modules, it is easier to develop and
-   review existing tests for specific parts of the application
- * Tests are now based on django-testscenarios project (co-developed) that
-   allows to use test scenarios and other advanced features from
-   python-testtools and python-testscenarios.
-
-Improvements to application core:
- * Bundles and Reports now use common privacy and ownership support code from
-   (co-developed) django-restricted-resources project. This allows objects to
-   be owned by a single user or by a group and allows application code to
-   clearly specify what kind of access should be granted to a particular object
-   and user.
- * Support for importing Dashboard Bundle Format versions 1.0, 1.0.1, 1.1 and 1.2
-   Apart from minor format improvements this adds support for binary attachments,
-   mime-type handling, tracking upstream projects with precise revision and optional
-   commit timestmap. This provides better meta-data (software context) to filter and
-   interpret tests results.
- * Importing Dashboard Bundle Format documents is now assisted with
-   (co-developed) linaro-dashboard-bundle project that supports document format
-   evolution (upgrading older documents to more recent formats) and document
-   validation. Import error messages now contain precise JSON schema violation
-   description that is easy to track and confirm.
- * Add support for PostgreSQL 8.4, this required a lot of small fixes where
-   SQLite was too forgiving and was not enforcing length limits that were set
-   in the model code.
- * Add new reporting framework composed of reports and data sources. 
-   This flexible framework (co-developed as Django-reports project) allows
-   third-party modules to extend Launch Control with new data sources
-   (encapsulated server side data mining) and reports (server side presentation
-   API that can tap into data sources)
- * Add new and still experimental GCC benchmark report written based on
-   requests from Linaro Toolchain Working Group. This report provides
-   interactive 2D chart rendered based on test result measurements.
- * Add a new XML-RPC call to create anonymous bundle streams
-
-Improvements to user interface:
- * Unified sign-in with local user&pass and LaunchpadSSO (based on OpenID)
- * DataBrowser feature has been dropped and replaced by manually constructed views.
-   This brings enormous usability improvements to various parts of the application.
- * All pages now show meaningful breadcrumbs to simplify navigation
- * It is now possible to view plain text attachments (log files) that accompany
-   test results. It is also possible to highlight a particular line from which
-   a test result was parsed.
- * It is now possible to see custom attributes defined for either test run or
-   test result.
- * The user interface now works correctly and looks similar on all major web
-   browsers including Internet Explorer 6+, Mozilla Firefox 3.5+ and Google
-   Chrome.
- * XML-RPC API page is now easier to read 
-
-
-Other changes:
- * Launch Control will now use CIA (cia.vc) to keep track of development and
-   publish commit messages to #linaro
- * Launch Control Tool (lc-tool) has been separated to a standalone project.
-   Code is now available at lp:launch-control-tool
- * Launch Control now depends on (co-developed) linaro-json package for JSON
-   handling and validation
- * Launch Control can now be deployed on Ubuntu from a semi-official PPA, a lot
-   of effort has been made to facilitate deployment, including ongoing
-   specification of Django application and project packaging for Debian and
-   co-developed django-debian project with deeper Debian administration and
-   maintainer script support.
- * The database schema has been changed significantly. There is no support for
-   automatically migrating data from 0.2 to 0.3. To retain your data export all
-   the bundles (lc-tool get) and re-import them to a fresh instance (lc-tool
-   put). After 0.3 we promise to deliver backwards compatible schema changes
-   and support for automatic database migration.
- * Launch Control now depends on (co-developed) versiontools to accurately
-   track development project version and expose this as internal API. This
-   makes it easier to create development snapshots and identify application
-   screen-shots (as the version is displayed in the header)
- * It's much easier to create a development environment composed of a running
-   dashboard instance (based on either SQLite or PostgreSQL) and some example
-   data using the new setup-dev-env.sh script.
- * Launch Control now requires Django 1.2. This adds better security against
-   Cross Site Request Forgery attacks, simplifies the codebase and consolidates
-   development effort on a single version of key technology. In addition some
-   template language improvements in Django 1.2 make templates much easier to
-   write (especially the improvement {% for %} tag and vastly improved {% if %}
-   tag. In the future we will also support Django 1.3.
- * Launch Control now makes a distinction between static content that is a part
-   of the source tree and static user-uploaded content. This simplifies
-   deployment on production web servers and provides a clear upgrade path for
-   Django 1.3 that supports this feature out of the box.
-
-The following bugs were fixed in this release:
-
-#744922   Unable to import SoftwarePackage with version longer than 32 characters
-#740591   Incorrect description of various stream types in the bundle stream detail page
-#740595   XML-RPCAPI view should have horizontal lines to delimit function blocks
-#740634   "Add test run" form "Time check performed" needs explanation
-#740638   "Add test case" form field "Units" in admin interface needs documentation
-#740639   "Relative index" field on "Add test result" admin form is not documented

=== removed file 'README'
--- README	2011-05-18 23:48:56 +0000
+++ README	1970-01-01 00:00:00 +0000
@@ -1,103 +0,0 @@
-Deployment instructions
-=======================
-
-Currently deployment is supported on Ubuntu Lucid/Maverick with sqlite and
-apache. Using other databases is likely to work but it was not tested for this
-release.
-
-Dashboard Requirements (debian package names, see setup.py meta-data for details and versions):
-    * python-django
-    * python-django-openid-auth
-    * python-docutils
-    * python-linaro-json
-    * python-linaro-dashboard-bundle
-    * python-django-pagination
-
-For testing/packaging also install:
-    * python-django-testscenarios
-
-Installation
-============
-
-See INSTALL
-
-Reporting Bugs
-==============
-
-All bugs should be reported to the launchpad project at
-https://bugs.launchpad.net/launch-control/+filebug
-
-Known Issues
-============
-
-1. Django 1.1 present on Ubuntu 10.04.1 LTS and possibly other installations
-suffers from a bug that prevents tests for django.contrib.auth to work
-correctly. This issue is has been reported and is tracked inside Launchpad:
-https://bugs.edge.launchpad.net/ubuntu/+source/python-django/+bug/650473
-
-
-Securing data views
-===================
-
-Data views are essentially arbitrary SQL queries performed by the database
-engine that are exposed to untrusted users. In all but extremely simple cases
-data views should be sand-boxed at database level to prevent data leaks or data
-loss.
-
-Sand-boxing prevents the user invoking the query (as understood by the database
-engine) from altering the data and constrains the tables and columns the user
-can reference.
-
-Currently this feature is only available when using PostgreSQL backend. To
-enable it run the following set of queries as the database administrator. 
-
-We first have to create a role (user) that will be used for dataview queries.
-The name of that user is derived from the name of the user owning the primary
-connection suffixed with "_dataview". Here, since we are using default
-deployment, the user is called "launchcontrol_dataview".
-
-The user must have the same password as the primary user. You can reference
-/etc/launch-control/default_database.conf for the value you are using.
-
-launchcontrol=# CREATE ROLE launchcontrol_dataview WITH OPTION LOGIN, PASSWORD {password};
-
-By default this new role has no permissions to do anything. We must explicitly
-grant each right. We'll allow selecting data from two tables outside of the
-dashboard.  Content types are a part of Django implementation details and do
-not contain any private data. The user table will allow queries to resolve user
-primary key to a username.
- 
-launchcontrol=# GRANT SELECT (username, id) ON TABLE auth_user TO launchcontrol_dataview;
-launchcontrol=# GRANT SELECT ON TABLE django_content_type TO launchcontrol_dataview;
-
-This step is larger, we explicitly allow selecting data from all the dashboard
-tables:
-
-launchcontrol=# GRANT SELECT ON TABLE 
-    dashboard_app_bundle,
-    dashboard_app_bundlestream,
-    dashboard_app_hardwaredevice,
-    dashboard_app_namedattribute,
-    dashboard_app_softwarepackage,
-    dashboard_app_softwaresource,
-    dashboard_app_test,
-    dashboard_app_testcase,
-    dashboard_app_testresult,
-    dashboard_app_testrun,
-    dashboard_app_testrun_devices,
-    dashboard_app_testrun_packages,
-    dashboard_app_testrun_sources
-TO launchcontrol_dataview;
-
-Finally we need to create or edit a small configuration file to make the
-dashboard use the constrained role. Since we are using django-debian many
-configuration variables traditionally configured via 'settings.py' can be
-defined in /etc/launch-control/settings.conf. By default that file is not
-created. You should create it and place following text inside:
-
-{
-        "use_dataview_database": true
-}
-
-That's it. Now restart the application and check that your data views still
-work.

=== added file 'README.obsolete.txt'
--- README.obsolete.txt	1970-01-01 00:00:00 +0000
+++ README.obsolete.txt	2013-09-19 17:47:28 +0000
@@ -0,0 +1,3 @@
+This package is obsolete.
+
+See http://git.linaro.org/gitweb?p=lava/lava-dashboard.git instead

=== removed file 'TODO'
--- TODO	2011-03-14 16:25:48 +0000
+++ TODO	1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-Things to solve sometime:
- * Silence the logging in "internal boom" test that shows up every single time

=== removed directory 'assets.src'
=== removed file 'assets.src/icons.xcf'
Binary files assets.src/icons.xcf	2010-12-20 11:48:23 +0000 and assets.src/icons.xcf	1970-01-01 00:00:00 +0000 differ
=== removed directory 'contrib'
=== removed file 'contrib/install.sh'
--- contrib/install.sh	2010-12-13 11:18:32 +0000
+++ contrib/install.sh	1970-01-01 00:00:00 +0000
@@ -1,84 +0,0 @@
-#!/bin/bash
-export LANG=C
-
-function get_deps() {
-    echo "Inspecting your system to determine dependencies"
-    
-    case "$(lsb_release -i -s)" in
-        Ubuntu)
-        ;;
-        
-        *)
-        echo "Your distribution is not supported"
-        exit 1
-        ;;
-    esac
-
-    case "$(lsb_release -r -s)" in
-        10.04)
-        SERVER_PKGS="python-django python-docutils python-simplejson"
-        CLIENT_PKGS="python-argparse"
-        TEST_PKGS="python-testscenarios python-setuptools python-coverage"
-        ;;
-        
-        *)
-        echo "This release of ubuntu is not supported"
-        exit 1
-    esac
-}
-
-function get_yes_no() {
-    local question="$1"
-    local default="${2:-y}"
-    local answer
-    while [ "x$answer" != "xy" -a "x$answer" != "xn" ]; do
-        read -p "$question [y/n, default $default] " answer
-        if [ "x$answer" = "x" ]; then
-            answer="$default"
-        fi
-    done
-    echo $answer
-}
-
-
-function install_deps() {
-    get_deps
-
-    if [ "$(get_yes_no "Do you want to install dependencies for the server?")" = "y" ]; then
-        PKGS="$PKGS $SERVER_PKGS"
-    fi
-    if [ "$(get_yes_no "Do you want to install dependencies for the client?")" = "y" ]; then
-        PKGS="$PKGS $CLIENT_PKGS"
-    fi
-    if [ "$(get_yes_no "Do you want to install dependencies for the test suite?")" = "y" ]; then
-        PKGS="$PKGS $TEST_PKGS"
-    fi
-
-    echo "About to install the following packages"
-    IFS=" "
-    for pkg in $PKGS; do
-        echo " * $pkg"
-    done
-    go=$(get_yes_no "Is this correct?" n)
-
-    if [ "$go" = "y" ]; then
-        sudo apt-get install $PKGS
-    fi
-}
-
-
-function main() {
-    echo "This script will help you to install launch-control on your system"
-    echo "Currently it can only install the required dependencies"
-
-    if [ "$(get_yes_no "Do you want to continue?")" != "y" ]; then
-        exit
-    fi
-    
-    install_deps
-
-}
-
-
-main
-

=== removed file 'contrib/virtualenv-install.sh'
--- contrib/virtualenv-install.sh	2011-01-10 09:39:19 +0000
+++ contrib/virtualenv-install.sh	1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
-#!/bin/sh
-set -e
-virtualenv --no-site-packages --clear /tmp/foo
-. /tmp/foo/bin/activate
-# 3rd party dependencies
-pip install simplejson django python-openid django-openid-auth django-pagination docutils
-# For launch-control itself
-pip install versiontools
-pip install linaro-json
-pip install linaro-dashboard-bundle
-pip install django-restricted-resource
-# For testing
-pip install django-testscenarios
-# Client side tools
-pip install launch-control-tool

=== removed directory 'dashboard_app'
=== removed file 'dashboard_app/__init__.py'
--- dashboard_app/__init__.py	2013-01-15 21:40:20 +0000
+++ dashboard_app/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
-# Copyright (C) 2010-2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Dashboard Application (package)
-"""
-
-__version__ = (0, 29, 0, "final", 0)

=== removed file 'dashboard_app/admin.py'
--- dashboard_app/admin.py	2013-04-01 08:50:05 +0000
+++ dashboard_app/admin.py	1970-01-01 00:00:00 +0000
@@ -1,228 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Administration interface of the Dashboard application
-"""
-
-from django import forms
-from django.contrib import admin
-from django.contrib.admin.actions import delete_selected
-from django.contrib.contenttypes import generic
-from django.utils.translation import ugettext as _
-
-from dashboard_app.models import (
-    Attachment,
-    Bundle,
-    BundleDeserializationError,
-    BundleStream,
-    HardwareDevice,
-    Image,
-    ImageSet,
-    LaunchpadBug,
-    NamedAttribute,
-    PMQABundleStream,
-    SoftwarePackage,
-    SoftwareSource,
-    Tag,
-    Test,
-    TestCase,
-    TestResult,
-    TestRun,
-    TestRunFilter,
-    TestRunFilterAttribute,
-    TestRunFilterSubscription,
-    TestDefinition,
-)
-
-
-class BundleAdmin(admin.ModelAdmin):
-
-    def bundle_stream_pathname(self, bundle):
-        return bundle.bundle_stream.pathname
-    bundle_stream_pathname.short_description = _("Bundle stream")
-
-    list_display = ('bundle_stream_pathname', 'content_filename',
-            'uploaded_by', 'uploaded_on', 'is_deserialized')
-    list_filter = ('bundle_stream',)
-    readonly_fields = ('is_deserialized',)
-    date_hierarchy = 'uploaded_on'
-    fieldsets = (
-        ('Document', {
-            'fields': ('_raw_content', '_gz_content', 'content_filename')}),
-        ('Upload Details', {
-            'fields': ('bundle_stream', 'uploaded_by')}),
-        ('Deserialization', {
-            'fields': ('is_deserialized',)}),
-    )
-
-
-class BundleDeserializationErrorAdmin(admin.ModelAdmin):
-    list_display = ('bundle', 'error_message')
-    search_fields = ('bundle__content_sha1',)
-
-
-class BundleStreamAdminForm(forms.ModelForm):
-    class Meta:
-        model = BundleStream
-
-    def clean(self):
-        cleaned_data = self.cleaned_data
-        if (cleaned_data.get('user', '') is not None and
-                cleaned_data.get('group') is not None):
-            raise forms.ValidationError('BundleStream cannot have both user '
-                    'and name set at the same time')
-        return super(BundleStreamAdminForm, self).clean()
-
-
-def cleanup_bundle_stream_selected(modeladmin, request, queryset):
-    """
-    This action cleans up the bundles from a bundle stream, without remove
-    the bundle stream itself.
-    """
-    my_modeladmin = BundleAdmin(Bundle, modeladmin.admin_site)
-    my_modeladmin.delete_selected_confirmation_template = 'admin/dashboard_app/cleanup_selected_bundle_confirmation.html'
-    my_queryset = None
-    if request.POST.get('post'):  # handle bundles
-        selected_bundles = request.POST.getlist('_selected_action')
-        my_queryset = Bundle.objects.filter(pk__in=selected_bundles)
-    else:  # handle bundle streams
-        for bundle_stream in queryset:
-            if my_queryset is None:
-                my_queryset = bundle_stream.bundles.all()
-            else:
-                my_queryset = my_queryset | bundle_stream.bundles.all()
-    return delete_selected(my_modeladmin, request, my_queryset)
-cleanup_bundle_stream_selected.short_description = "Clean up selected %(verbose_name_plural)s"
-
-
-class BundleStreamAdmin(admin.ModelAdmin):
-    actions = [cleanup_bundle_stream_selected]
-    form = BundleStreamAdminForm
-    list_display = ('pathname', 'user', 'group', 'slug', 'is_public', 'is_anonymous', 'name')
-    list_filter = ('is_public', 'is_anonymous')
-    prepopulated_fields = {"slug": ("name",)}
-    readonly_fields = ('pathname',)
-    fieldsets = (
-            ('Name and description', {
-                'fields': ('name', 'slug', 'pathname')}),
-            ('Ownership', {
-                'fields': ('user', 'group')}),
-            ('Access Rights', {
-                'fields': ('is_public', 'is_anonymous')}),
-            )
-
-
-class SoftwarePackageAdmin(admin.ModelAdmin):
-    list_display = ('name', 'version')
-    search_fields = ('name', 'version')
-
-
-class SoftwareSourceAdmin(admin.ModelAdmin):
-    list_display = ('project_name', 'branch_url', 'branch_vcs',
-                    'branch_revision', 'commit_timestamp')
-    list_filter = ('project_name',)
-    search_fields = ('project_name', 'branch_url')
-
-
-class HardwareDeviceAdmin(admin.ModelAdmin):
-    class NamedAttributeInline(generic.GenericTabularInline):
-        model = NamedAttribute
-    list_display = ('description', 'device_type')
-    list_filter = ('device_type',)
-    search_fields = ('description',)
-    inlines = [NamedAttributeInline]
-
-
-class TestCaseAdmin(admin.ModelAdmin):
-    list_display = ('test_case_id', 'test',)
-    list_filter = ('test',)
-
-
-class TestAdmin(admin.ModelAdmin):
-    pass
-
-
-class TestResultAdmin(admin.ModelAdmin):
-    class NamedAttributeInline(generic.GenericTabularInline):
-        model = NamedAttribute
-    list_display = ('__unicode__', 'test', 'test_case', 'result', 'measurement')
-    list_filter = ('test_case', 'result')
-    inlines = [NamedAttributeInline]
-
-
-class TestRunAdmin(admin.ModelAdmin):
-    class NamedAttributeInline(generic.GenericTabularInline):
-        model = NamedAttribute
-    list_filter = ('test'),
-    list_display = (
-        'test',
-        'analyzer_assigned_uuid',
-        'bundle',
-        'analyzer_assigned_date',
-        'import_assigned_date')
-    inlines = [NamedAttributeInline]
-
-
-class ImageAdmin(admin.ModelAdmin):
-    save_as = True
-
-
-class ImageSetAdmin(admin.ModelAdmin):
-    class Media:
-        css = {
-            "all": ("dashboard_app/css/wider-filter-horizontal.css",)
-        }
-    filter_horizontal = ['images']
-    save_as = True
-
-
-class LaunchpadBugAdmin(admin.ModelAdmin):
-    raw_id_fields = ['test_runs']
-
-
-class TestRunFilterAdmin(admin.ModelAdmin):
-    filter_horizontal = ['bundle_streams']
-    class TestRunFilterAttributeInline(admin.TabularInline):
-        model = TestRunFilterAttribute
-    inlines = [TestRunFilterAttributeInline]
-    save_as = True
-
-
-class TestDefinitionAdmin(admin.ModelAdmin):
-    list_display = ('name', 'version')
-
-admin.site.register(Attachment)
-admin.site.register(Bundle, BundleAdmin)
-admin.site.register(BundleDeserializationError, BundleDeserializationErrorAdmin)
-admin.site.register(BundleStream, BundleStreamAdmin)
-admin.site.register(HardwareDevice, HardwareDeviceAdmin)
-admin.site.register(Image, ImageAdmin)
-admin.site.register(ImageSet, ImageSetAdmin)
-admin.site.register(LaunchpadBug, LaunchpadBugAdmin)
-admin.site.register(PMQABundleStream)
-admin.site.register(SoftwarePackage, SoftwarePackageAdmin)
-admin.site.register(SoftwareSource, SoftwareSourceAdmin)
-admin.site.register(Test, TestAdmin)
-admin.site.register(TestCase, TestCaseAdmin)
-admin.site.register(TestResult, TestResultAdmin)
-admin.site.register(TestRun, TestRunAdmin)
-admin.site.register(TestRunFilter, TestRunFilterAdmin)
-admin.site.register(TestRunFilterSubscription)
-admin.site.register(Tag)
-admin.site.register(TestDefinition, TestDefinitionAdmin)

=== removed file 'dashboard_app/bread_crumbs.py'
--- dashboard_app/bread_crumbs.py	2011-09-30 13:34:54 +0000
+++ dashboard_app/bread_crumbs.py	1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-"""
-Deprecated bread crumb module.
-
-Bread crubms are now part of lava server
-"""
-
-from lava_server.bread_crumbs import BreadCrumb, LiveBreadCrumb, BreadCrumbTrail

=== removed file 'dashboard_app/extension.py'
--- dashboard_app/extension.py	2013-09-13 13:13:30 +0000
+++ dashboard_app/extension.py	1970-01-01 00:00:00 +0000
@@ -1,104 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-import os
-
-from lava_server.extension import LavaServerExtension, Menu
-
-
-class DashboardExtension(LavaServerExtension):
-
-    @property
-    def app_name(self):
-        return "dashboard_app"
-
-    @property
-    def name(self):
-        return "Dashboard"
-
-    @property
-    def main_view_name(self):
-        return "dashboard_app.views.index"
-
-    def get_menu(self):
-        from django.conf import settings
-        from django.core.urlresolvers import reverse
-
-        menu = super(DashboardExtension, self).get_menu()
-        subm = []
-        menu.sub_menu = subm
-        subm.append(Menu("Image Reports", reverse("dashboard_app.views.images.image_report_list")))
-        subm.append(Menu("Filters", reverse("dashboard_app.views.filters.views.filters_list")))
-        subm.append(Menu("Bundle Streams", reverse("dashboard_app.views.bundle_stream_list")))
-        if not settings.DATAVIEW_HIDE:
-            subm.append(Menu("Data Views", reverse("dashboard_app.views.data_view_list")))
-        if not settings.DATAREPORTS_HIDE:
-            subm.append(Menu("Reports", reverse("dashboard_app.views.report_list")))
-        subm.append(Menu("Test Definitions", reverse("dashboard_app.views.test_definition")))
-        subm.append(Menu("PM-QA", reverse("dashboard_app.views.pmqa.pmqa_view")))
-
-        return menu
-
-    @property
-    def description(self):
-        return "Validation Dashboard"
-
-    @property
-    def version(self):
-        import dashboard_app
-        import versiontools
-        return versiontools.format_version(dashboard_app.__version__, hint=dashboard_app)
-
-    @property
-    def api_class(self):
-        from dashboard_app.xmlrpc import DashboardAPI
-        return DashboardAPI
-
-    def contribute_to_settings(self, settings_module):
-        super(DashboardExtension, self).contribute_to_settings(settings_module)
-        settings_module['INSTALLED_APPS'].append("linaro_django_pagination")
-        settings_module['MIDDLEWARE_CLASSES'].append(
-            'linaro_django_pagination.middleware.PaginationMiddleware')
-        root_dir = os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))
-        settings_module['DATAVIEW_DIRS'] = [
-            os.path.join(root_dir, 'examples', 'views'),
-            os.path.join(root_dir, 'production', 'views')]
-        settings_module['DATAREPORT_DIRS'] = [
-            os.path.join(root_dir, 'examples', 'reports'),
-            os.path.join(root_dir, 'production', 'reports')]
-        prepend_label_apps = settings_module.get('STATICFILES_PREPEND_LABEL_APPS', [])
-        if self.app_name in prepend_label_apps:
-            prepend_label_apps.remove(self.app_name)
-
-    def contribute_to_settings_ex(self, settings_module, settings_object):
-        settings_module['DATAVIEW_DIRS'] = settings_object._settings.get(
-            "DATAVIEW_DIRS", [])
-        settings_module['DATAVIEW_HIDE'] = settings_object._settings.get(
-            "DATAVIEW_HIDE", False)
-        settings_module['DATAREPORT_DIRS'] = settings_object._settings.get(
-            "DATAREPORT_DIRS", [])
-        settings_module['DATAREPORTS_HIDE'] = settings_object._settings.get(
-            "DATAREPORTS_HIDE", False)
-
-        # Enable constrained dataview database if requested
-        if settings_object._settings.get("use_dataview_database"):
-            # Copy everything from the default database and append _dataview to user
-            # name. The rest is out of scope (making sure it's actually setup
-            # properly, having permissions to login, permissions to view proper data)
-            settings_module['DATABASES']['dataview'] = dict(settings_module['DATABASES']['default'])
-            settings_module['DATABASES']['dataview']['USER'] += "_dataview"

=== removed file 'dashboard_app/filters.py'
--- dashboard_app/filters.py	2013-01-09 00:15:10 +0000
+++ dashboard_app/filters.py	1970-01-01 00:00:00 +0000
@@ -1,420 +0,0 @@
-
-# A test run filter allows a user to produce an ordered list of results of
-# interest.
-
-# The data that makes up a filter are:
-#
-# * A non-empty set of bundle streams
-# * A possibly empty set of (attribute-name, attribute-value) pairs
-# * A possibly empty list of tests, each of which has a possibly empty list of
-#   test cases
-# * An optional build number attribute name
-
-# A filter matches a test run if:
-#
-# * It is part of a bundle that is in one of the specified streams
-# * It has all the attribute names with the specified values (or there are no
-#   attributes specified)
-# * The test of the test run is one of those specified (or there are no test
-#   runs specified)
-# * One of the results of the test run is one of those specified (or there are
-#   no test cases specified)
-# * The build number attribute is present, if specified.
-#
-# The test runs matching a filter are grouped, either by the upload date of
-# the bundle or by the value of the build number attribute.
-
-# We define several representations for this data:
-#
-# * One is the TestRunFilter and related tables (the "model represenation").
-#   These have some representation specific metadata that does not relate to
-#   the test runs the filter selects: names, owner, the "public" flag.
-
-# * One is the natural Python data structure for the data (the "in-memory
-#   representation"), i.e.
-#     {
-#         bundle_streams: [<BundleStream objects>],
-#         attributes: [(attr-name, attr-value)],
-#         tests: [{"test": <Test instance>, "test_cases":[<TestCase instances>]}],
-#         build_number_attribute: attr-name-or-None,
-#         uploaded_by: <User instance-or-None>,
-#     }
-#   This is the representation that is used to evaluate a filter (so that
-#   previewing new filters can be done without having to create a
-#   TestRunFilter instance that we carefully don't save to the database --
-#   which doesn't work very well anyway with all the ManyToMany relations
-#   involved)
-
-# * The final one is the TRFForm object defined in
-#   dashboard_app.views.filters.forms (the "form representation")
-#   (pedantically, the rendered form of this is yet another
-#   representation...).  This representation is the only one other than the
-#   model objects to include the name/owner/public metadata.
-
-# evaluate_filter returns a sort of fake QuerySet.  Iterating over it returns
-# "FilterMatch" objects, whose attributes are described in the class
-# defintion.  A FilterMatch also has a serializable representation:
-#
-# {
-#       'tag': either a stringified date (bundle__uploaded_on) or a build number
-#       'test_runs': [{
-#           'test_id': test_id
-#           'link': link-to-test-run,
-#           'passes': int, 'fails': int, 'skips': int, 'total': int,
-#           # only present if filter specifies cases for this test:
-#           'specific_results': [{
-#               'test_case_id': test_case_id,
-#               'link': link-to-test-result,
-#               'result': pass/fail/skip/unknown,
-#               'measurement': string-containing-decimal-or-None,
-#               'units': units,
-#               }],
-#           }]
-#       # Only present if filter does not specify tests:
-#       'pass_count': int,
-#       'fail_count': int,
-# }
-
-import datetime
-
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.sites.models import Site
-from django.core.exceptions import ImproperlyConfigured
-from django.db import models
-from django.db.models.sql.aggregates import Aggregate as SQLAggregate
-
-from dashboard_app.models import (
-    BundleStream,
-    NamedAttribute,
-    TestResult,
-    TestRun,
-    )
-
-
-class FilterMatch(object):
-    """A non-database object that represents the way a filter matches a test_run.
-
-    Returned by TestRunFilter.matches_against_bundle and evaluate_filter.
-    """
-
-    filter = None # The model representation of the filter (this is only set
-                  # by matches_against_bundle)
-    filter_data = None # The in-memory representation of the filter.
-    tag = None # either a date (bundle__uploaded_on) or a build number
-
-    test_runs = None # Will be all test runs from the bundle if
-                     # filter_data['tests'] is empty, will just be the test
-                     # runs with matching tests if not.
-
-    specific_results = None # Will stay none unless filter specifies a test case
-
-    pass_count = None # Only filled out for filters that dont specify a test
-    result_count = None # Ditto
-
-    def serializable(self, include_links=True):
-        cases_by_test = {}
-        for test in self.filter_data['tests']:
-            # Not right if filter specifies a test more than once...
-            if test['test_cases']:
-                cases_by_test[test['test']] = test['test_cases']
-        test_runs = []
-
-        domain = '???'
-        try:
-            site = Site.objects.get_current()
-        except (Site.DoesNotExist, ImproperlyConfigured):
-            pass
-        else:
-            domain = site.domain
-        url_prefix = 'http://%s' % domain
-
-        for tr in self.test_runs:
-            d = {
-                'test_id': tr.test.test_id,
-                'pass': 0,
-                'fail': 0,
-                'skip': 0,
-                'unknown': 0,
-                'total': 0,
-                }
-            if include_links:
-                d['link'] =  url_prefix + tr.get_absolute_url()
-            if tr.test in cases_by_test:
-                results = d['specific_results'] = []
-                for result in self.specific_results:
-                    if result.test_run == tr:
-                        result_str = TestResult.RESULT_MAP[result.result]
-                        result_data = {
-                            'test_case_id': result.test_case.test_case_id,
-                            'result': result_str,
-                            }
-                        if include_links:
-                            result_data['link'] =  url_prefix + result.get_absolute_url()
-                        if result.measurement is not None:
-                            result_data['measurement'] = str(result.measurement)
-                        if result.units is not None:
-                            result_data['units'] = str(result.units)
-                        results.append(result_data)
-                        d[result_str] += 1
-                        d['total'] += 1
-            else:
-                d['pass'] = tr.denormalization.count_pass
-                d['fail'] = tr.denormalization.count_fail
-                d['skip'] = tr.denormalization.count_skip
-                d['unknown'] = tr.denormalization.count_unknown
-                d['total'] = tr.denormalization.count_all()
-            test_runs.append(d)
-        r = {
-            'tag': str(self.tag),
-            'test_runs': test_runs,
-            }
-        if self.pass_count is not None:
-            r['pass_count'] = self.pass_count
-        if self.result_count is not None:
-            r['result_count'] = self.result_count
-        return r
-
-    def _format_test_result(self, result):
-        prefix = result.test_case.test.test_id + ':' + result.test_case.test_case_id + ' '
-        if result.test_case.units:
-            return prefix + '%s%s' % (result.measurement, result.units)
-        else:
-            return prefix + result.RESULT_MAP[result.result]
-
-    def _format_test_run(self, tr):
-        return "%s %s pass / %s total" % (
-            tr.test.test_id,
-            tr.denormalization.count_pass,
-            tr.denormalization.count_all())
-
-    def _format_many_test_runs(self):
-        return "%s pass / %s total" % (self.pass_count, self.result_count)
-
-    def format_for_mail(self):
-        r = [' ~%s/%s ' % (self.filter.owner.username, self.filter.name)]
-        if not self.filter_data['tests']:
-            r.append(self._format_many_test_runs())
-        else:
-            for test in self.filter_data['tests']:
-                if not test['test_cases']:
-                    for tr in self.test_runs:
-                        if tr.test == test.test:
-                            r.append('\n    ')
-                            r.append(self._format_test_run(tr))
-                for test_case in test['test_cases']:
-                    for result in self.specific_results:
-                        if result.test_case.id == test_case.id:
-                            r.append('\n    ')
-                            r.append(self._format_test_result(result))
-        r.append('\n')
-        return ''.join(r)
-
-
-class MatchMakingQuerySet(object):
-    """Wrap a QuerySet and construct FilterMatchs from what the wrapped query
-    set returns.
-
-    Just enough of the QuerySet API to work with DataTable (i.e. pretend
-    ordering and real slicing)."""
-
-    model = TestRun
-
-    def __init__(self, queryset, filter_data, prefetch_related):
-        self.queryset = queryset
-        self.filter_data = filter_data
-        self.prefetch_related = prefetch_related
-        if filter_data.get('build_number_attribute'):
-            self.key = 'build_number'
-            self.key_name = 'Build'
-        else:
-            self.key = 'bundle__uploaded_on'
-            self.key_name = 'Uploaded On'
-
-    def _makeMatches(self, data):
-        test_run_ids = set()
-        for datum in data:
-            test_run_ids.update(datum['id__arrayagg'])
-        r = []
-        trs = TestRun.objects.filter(id__in=test_run_ids).select_related(
-            'denormalization', 'bundle', 'bundle__bundle_stream', 'test').prefetch_related(
-            *self.prefetch_related)
-        trs_by_id = {}
-        for tr in trs:
-            trs_by_id[tr.id] = tr
-        case_ids = set()
-        for t in self.filter_data['tests']:
-            for case in t['test_cases']:
-                case_ids.add(case.id)
-        if case_ids:
-            result_ids_by_tr_id = {}
-            results_by_tr_id = {}
-            values = TestResult.objects.filter(
-                test_case__id__in=case_ids,
-                test_run__id__in=test_run_ids).values_list(
-                'test_run__id', 'id')
-            result_ids = set()
-            for v in values:
-                result_ids_by_tr_id.setdefault(v[0], []).append(v[1])
-                result_ids.add(v[1])
-
-            results_by_id = {}
-            for result in TestResult.objects.filter(
-                id__in=list(result_ids)).select_related(
-                'test', 'test_case', 'test_run__bundle__bundle_stream'):
-                results_by_id[result.id] = result
-
-            for tr_id, result_ids in result_ids_by_tr_id.items():
-                rs = results_by_tr_id[tr_id] = []
-                for result_id in result_ids:
-                    rs.append(results_by_id[result_id])
-        for datum in data:
-            trs = []
-            for tr_id in set(datum['id__arrayagg']):
-                trs.append(trs_by_id[tr_id])
-            match = FilterMatch()
-            match.test_runs = trs
-            match.filter_data = self.filter_data
-            match.tag = datum[self.key]
-            if case_ids:
-                match.specific_results = []
-                for tr_id in set(datum['id__arrayagg']):
-                    match.specific_results.extend(results_by_tr_id.get(tr_id, []))
-            else:
-                match.pass_count = sum(tr.denormalization.count_pass for tr in trs)
-                match.result_count = sum(tr.denormalization.count_all() for tr in trs)
-            r.append(match)
-        return iter(r)
-
-    def _wrap(self, queryset, **kw):
-        return self.__class__(queryset, self.filter_data, self.prefetch_related, **kw)
-
-    def order_by(self, *args):
-        # the generic tables code calls this even when it shouldn't...
-        return self
-
-    def since(self, since):
-        if self.key == 'build_number':
-            q = self.queryset.extra(
-                where=['convert_to_integer("dashboard_app_namedattribute"."value") > %d' % since]
-                )
-        else:
-            assert isinstance(since, datetime.datetime)
-            q = self.queryset.filter(bundle__uploaded_on__gt=since)
-        return self._wrap(q)
-
-    def with_tags(self, tag1, tag2):
-        if self.key == 'build_number':
-            q = self.queryset.extra(
-                where=['convert_to_integer("dashboard_app_namedattribute"."value") in (%s, %s)' % (tag1, tag2)]
-                )
-        else:
-            tag1 = datetime.datetime.strptime(tag1, "%Y-%m-%d %H:%M:%S.%f")
-            tag2 = datetime.datetime.strptime(tag2, "%Y-%m-%d %H:%M:%S.%f")
-            q = self.queryset.filter(bundle__uploaded_on__in=(tag1, tag2))
-        matches = list(self._wrap(q))
-        if matches[0].tag == tag1:
-            return matches
-        else:
-            matches.reverse()
-            return matches
-
-    def count(self):
-        return self.queryset.count()
-
-    def __getitem__(self, item):
-        return self._wrap(self.queryset[item])
-
-    def __iter__(self):
-        data = list(self.queryset)
-        return self._makeMatches(data)
-
-
-class SQLArrayAgg(SQLAggregate):
-    sql_function = 'array_agg'
-
-
-class ArrayAgg(models.Aggregate):
-    name = 'ArrayAgg'
-    def add_to_query(self, query, alias, col, source, is_summary):
-        aggregate = SQLArrayAgg(
-            col, source=source, is_summary=is_summary, **self.extra)
-        # For way more detail than you want about what this next line is for,
-        # see
-        # http://voices.canonical.com/michael.hudson/2012/09/02/using-postgres-array_agg-from-django/
-        aggregate.field = models.DecimalField() # vomit
-        query.aggregates[alias] = aggregate
-
-
-# given filter:
-# select from testrun
-#  where testrun.bundle in filter.bundle_streams ^ accessible_bundles
-#    and testrun has attribute with key = key1 and value = value1
-#    and testrun has attribute with key = key2 and value = value2
-#    and               ...
-#    and testrun has attribute with key = keyN and value = valueN
-#    and testrun has any of the tests/testcases requested
-#    [and testrun has attribute with key = build_number_attribute]
-#    [and testrun.bundle.uploaded_by = uploaded_by]
-def evaluate_filter(user, filter_data, prefetch_related=[], descending=True):
-    accessible_bundle_streams = BundleStream.objects.accessible_by_principal(
-        user)
-    bs_ids = list(
-        accessible_bundle_streams.filter(
-            id__in=[bs.id for bs in filter_data['bundle_streams']]).values_list('id', flat=True))
-    conditions = [models.Q(bundle__bundle_stream__id__in=bs_ids)]
-
-    content_type_id = ContentType.objects.get_for_model(TestRun).id
-
-    for (name, value) in filter_data['attributes']:
-        # We punch through the generic relation abstraction here for 100x
-        # better performance.
-        conditions.append(
-            models.Q(id__in=NamedAttribute.objects.filter(
-                name=name, value=value, content_type_id=content_type_id
-                ).values('object_id')))
-
-    test_condition = None
-    for test in filter_data.get('tests', []):
-        case_ids = set()
-        for test_case in test.get('test_cases', []):
-            case_ids.add(test_case.id)
-        if case_ids:
-            q = models.Q(
-                test__id=test['test'].id,
-                test_results__test_case__id__in=case_ids)
-        else:
-            q = models.Q(test__id=test['test'].id)
-        if test_condition:
-            test_condition = test_condition | q
-        else:
-            test_condition = q
-    if test_condition:
-        conditions.append(test_condition)
-
-    if filter_data.get('uploaded_by'):
-        conditions.append(models.Q(bundle__uploaded_by=filter_data['uploaded_by']))
-
-    testruns = TestRun.objects.filter(*conditions)
-
-    if filter_data.get('build_number_attribute'):
-        if descending:
-            ob = ['-build_number']
-        else:
-            ob = ['build_number']
-        testruns = testruns.filter(
-            attributes__name=filter_data['build_number_attribute']).extra(
-            select={
-                'build_number': 'convert_to_integer("dashboard_app_namedattribute"."value")',
-                },
-            where=['convert_to_integer("dashboard_app_namedattribute"."value") IS NOT NULL']).extra(
-            order_by=ob,
-            ).values('build_number').annotate(ArrayAgg('id'))
-    else:
-        if descending:
-            ob = '-bundle__uploaded_on'
-        else:
-            ob = 'bundle__uploaded_on'
-        testruns = testruns.order_by(ob).values(
-            'bundle__uploaded_on').annotate(ArrayAgg('id'))
-
-    return MatchMakingQuerySet(testruns, filter_data, prefetch_related)

=== removed directory 'dashboard_app/fixtures'
=== removed file 'dashboard_app/fixtures/hacking_admin_user.json'
--- dashboard_app/fixtures/hacking_admin_user.json	2010-12-20 09:45:31 +0000
+++ dashboard_app/fixtures/hacking_admin_user.json	1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-[
-    {
-        "pk": 1, 
-        "model": "auth.user", 
-        "fields": {
-            "username": "admin", 
-            "first_name": "", 
-            "last_name": "", 
-            "is_active": true, 
-            "is_superuser": true, 
-            "is_staff": true, 
-            "last_login": "2010-12-17 15:51:51", 
-            "groups": [], 
-            "user_permissions": [], 
-            "password": "sha1$851de$ff65ef6a15636d06c2bf084ef9f5f78c51bca4d5", 
-            "email": "admin@example.org", 
-            "date_joined": "2010-12-17 15:51:32"
-        }
-    }
-]

=== removed file 'dashboard_app/fixtures/hacking_gcc_bundle_stream.json'
--- dashboard_app/fixtures/hacking_gcc_bundle_stream.json	2011-03-18 12:28:50 +0000
+++ dashboard_app/fixtures/hacking_gcc_bundle_stream.json	1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
-[
-    {
-        "pk": 2, 
-        "model": "dashboard_app.bundlestream", 
-        "fields": {
-            "pathname": "/anonymous/gcc/", 
-            "group": null, 
-            "user": 1, 
-            "name": "Sample benchmark data from Linaro Toolchain Working Group", 
-            "slug": "gcc",
-            "is_public": true,
-            "is_anonymous": true
-        }
-    }
-]

=== removed file 'dashboard_app/fixtures/hacking_initial_bundle_stream.json'
--- dashboard_app/fixtures/hacking_initial_bundle_stream.json	2011-02-04 15:23:15 +0000
+++ dashboard_app/fixtures/hacking_initial_bundle_stream.json	1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
-[
-    {
-        "pk": 1, 
-        "model": "dashboard_app.bundlestream", 
-        "fields": {
-            "pathname": "/anonymous/", 
-            "group": null, 
-            "user": 1, 
-            "name": "", 
-            "slug": "",
-            "is_public": true,
-            "is_anonymous": true
-        }
-    }
-]

=== removed file 'dashboard_app/fixtures/hacking_localhost_site.json'
--- dashboard_app/fixtures/hacking_localhost_site.json	2010-12-20 09:45:31 +0000
+++ dashboard_app/fixtures/hacking_localhost_site.json	1970-01-01 00:00:00 +0000
@@ -1,10 +0,0 @@
-[
-    {
-        "pk": 1, 
-        "model": "sites.site", 
-        "fields": {
-            "domain": "localhost:8000", 
-            "name": "localhost:8000"
-        }
-    }
-]
\ No newline at end of file

=== removed file 'dashboard_app/fixtures/test_run_detail.json'
--- dashboard_app/fixtures/test_run_detail.json	2012-01-30 10:22:06 +0000
+++ dashboard_app/fixtures/test_run_detail.json	1970-01-01 00:00:00 +0000
@@ -1,285 +0,0 @@
-[
-    {
-        "pk": 1, 
-        "model": "dashboard_app.bundlestream", 
-        "fields": {
-            "pathname": "/anonymous/", 
-            "group": null, 
-            "user": null, 
-            "name": "anonymous", 
-            "slug": "",
-            "is_public": true,
-            "is_anonymous": true
-        }
-    }, 
-    {
-        "pk": 1, 
-        "model": "dashboard_app.bundle", 
-        "fields": {
-            "content_sha1": "e71c65065b18ede68b6512bf0d20790d06f718f2", 
-            "bundle_stream": 1, 
-            "uploaded_on": "2010-12-14 14:24:38", 
-            "_raw_content": "bundles/bundle-1", 
-            "uploaded_by": null, 
-            "content_filename": "gmpbench1291774485.0", 
-            "is_deserialized": true
-        }
-    }, 
-    {
-        "pk": 1, 
-        "model": "dashboard_app.test", 
-        "fields": {
-            "test_id": "gmpbench", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 1, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchbasemultiply", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 2, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchbasedivide", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 3, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchbasegcd", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 4, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchbasegcdext", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 5, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchbase", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 6, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchapprsa", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 7, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchapppi", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 8, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbenchapp", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 9, 
-        "model": "dashboard_app.testcase", 
-        "fields": {
-            "test": 1, 
-            "units": "operations/s", 
-            "test_case_id": "GMPbench", 
-            "name": ""
-        }
-    }, 
-    {
-        "pk": 1, 
-        "model": "dashboard_app.testrun", 
-        "fields": {
-            "sw_image_desc": "Ubuntu 10.04.1 LTS", 
-            "analyzer_assigned_date": "2010-12-08 07:44:45", 
-            "bundle": 1, 
-            "time_check_performed": false, 
-            "devices": [ ], 
-            "analyzer_assigned_uuid": "19bbbb9a-02a0-11e0-b91e-0015587c0f4d", 
-            "test": 1, 
-            "import_assigned_date": "2010-12-14 14:24:39", 
-            "packages": [ ]
-        }
-    }, 
-    {
-        "pk": 1, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "5413.4", 
-            "message": null, 
-            "test_case": 1, 
-            "result": 0,
-            "relative_index": 1
-        }
-    }, 
-    {
-        "pk": 2, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "3183.2", 
-            "message": null, 
-            "test_case": 2, 
-            "result": 0,
-            "relative_index": 2
-        }
-    }, 
-    {
-        "pk": 3, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "1196.3", 
-            "message": null, 
-            "test_case": 3, 
-            "result": 0,
-            "relative_index": 3
-        }
-    }, 
-    {
-        "pk": 4, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "728.05", 
-            "message": null, 
-            "test_case": 4, 
-            "result": 0,
-            "relative_index": 4
-        }
-    }, 
-    {
-        "pk": 5, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "2524.1", 
-            "message": null, 
-            "test_case": 5, 
-            "result": 0,
-            "relative_index": 5
-        }
-    }, 
-    {
-        "pk": 6, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "612.01", 
-            "message": null, 
-            "test_case": 6, 
-            "result": 0,
-            "relative_index": 6
-        }
-    }, 
-    {
-        "pk": 7, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "7.1672", 
-            "message": null, 
-            "test_case": 7, 
-            "result": 0,
-            "relative_index": 7
-        }
-    }, 
-    {
-        "pk": 8, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "66.23", 
-            "message": null, 
-            "test_case": 8, 
-            "result": 0,
-            "relative_index": 8
-        }
-    }, 
-    {
-        "pk": 9, 
-        "model": "dashboard_app.testresult", 
-        "fields": {
-            "test_run": 1, 
-            "timestamp": null, 
-            "microseconds": null, 
-            "filename": null, 
-            "lineno": null, 
-            "measurement": "408.87", 
-            "message": null, 
-            "test_case": 9, 
-            "result": 0,
-            "relative_index": 9
-        }
-    }
-]

=== removed file 'dashboard_app/helpers.py'
--- dashboard_app/helpers.py	2013-04-01 11:04:15 +0000
+++ dashboard_app/helpers.py	1970-01-01 00:00:00 +0000
@@ -1,851 +0,0 @@
-"""
-Module with non-database helper classes
-"""
-
-from uuid import UUID
-import base64
-import logging
-import time
-
-from django.core.files.base import ContentFile
-from django.core.exceptions import ObjectDoesNotExist
-from django.db import connection, transaction, IntegrityError
-from linaro_dashboard_bundle.errors import DocumentFormatError
-from linaro_dashboard_bundle.evolution import DocumentEvolution
-from linaro_dashboard_bundle.io import DocumentIO
-from json_schema_validator.extensions import datetime_extension, timedelta_extension
-
-
-PROFILE_LOGGING = False
-
-
-def is_postgres():
-    return (connection.settings_dict['ENGINE']
-            == 'django.db.backends.postgresql_psycopg2')
-
-
-class IBundleFormatImporter(object):
-    """
-    Interface for bundle format importers.
-    """
-
-    def import_document(self, s_bundle, doc):
-        """
-        Import document in a supported format and tie it to the
-        specified server side DashboardBundle model (s_bundle)
-
-        :Discussion:
-            Imports specified document in a supported format and tie it
-            to the specified server side DashboardBundle model
-            (s_bundle)
-
-        :Return value:
-            None
-
-        :Exceptions raised:
-            ValueError
-            TypeError
-            others (?)
-        """
-        raise NotImplementedError(self.import_document)
-
-
-class BundleFormatImporter_1_0(IBundleFormatImporter):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.0"
-    """
-
-    def import_document(self, s_bundle, doc):
-        """
-        Import specified bundle document into the database.
-        """
-        self._content_files = []
-        self._import_sanity_check(doc)
-        try:
-            self._import_document_with_transaction(s_bundle, doc)
-        except IntegrityError:
-            self._remove_created_files()
-            raise
-
-    def _remove_created_files(self):
-        """
-        Remove any files that may have already been flushed to disk. Otherwise
-        the transaction handling should rollback anything evil that was
-        happening while we were here
-        """
-        for content_file in self._content_files:
-            content_file.delete(save=False)
-
-    def _import_sanity_check(self, doc):
-        """
-        Sanity check before any import is attempted.
-
-        This prevents InternalError (but is racy with other transactions).
-        Still it's a little bit better to report the exception raised below
-        rather than the IntegrityError that would have been raised otherwise.
-
-        The code copes with both (using transactions around _import_document()
-        and _remove_created_files() that gets called if something is wrong)
-        """
-        from dashboard_app.models import TestRun
-
-        for test_run in doc.get("test_runs", []):
-            analyzer_assigned_uuid = test_run["analyzer_assigned_uuid"]
-            if TestRun.objects.filter(
-                analyzer_assigned_uuid=analyzer_assigned_uuid).exists():
-                raise ValueError("A test with UUID {0} already exists".format(analyzer_assigned_uuid))
-
-    @transaction.commit_on_success
-    def _import_document_with_transaction(self, s_bundle, doc):
-        """
-        Note: This function uses commit_on_success to ensure the database is in
-        a consistent state after IntegrityErrors that would clog the
-        transaction on pgsql. Since transactions will not rollback any files we
-        created in the meantime there is a helper that cleans attachments in
-        case something goes wrong
-        """
-        self._import_document(s_bundle, doc)
-
-    def _import_document(self, s_bundle, doc):
-        for c_test_run in doc.get("test_runs", []):
-            self._import_test_run(c_test_run, s_bundle)
-
-    def __init__(self):
-        self._qc = 0
-        self._time = time.time()
-
-    def _log(self, method_name):
-        if PROFILE_LOGGING:
-            t = time.time() - self._time
-            if t > 0.1:
-                p = '**'
-            else:
-                p = '  '
-            logging.warning(
-                '%s %s %.2f %d', p, method_name, t,
-                len(connection.queries) - self._qc)
-            self._qc = len(connection.queries)
-            self._time = time.time()
-
-    def _import_test_run(self, c_test_run, s_bundle):
-        """
-        Import TestRun
-        """
-        from dashboard_app.models import TestRun
-
-        s_test = self._import_test(c_test_run)
-        analyzer_assigned_uuid = UUID(c_test_run["analyzer_assigned_uuid"])
-        s_test_run = TestRun.objects.create(
-            bundle = s_bundle,
-            test = s_test,
-            analyzer_assigned_uuid = str(analyzer_assigned_uuid),
-            analyzer_assigned_date = datetime_extension.from_json(
-                # required by schema
-                c_test_run["analyzer_assigned_date"]),
-            time_check_performed = (
-                # required by schema
-                c_test_run["time_check_performed"]),
-        )
-        # needed for foreign key models below
-        s_test_run.save()
-        # import all the bits and pieces
-        self._log('starting')
-        self._import_test_results(c_test_run, s_test_run)
-        self._log('results')
-        self._import_attachments(c_test_run, s_test_run)
-        self._log('attachments')
-        self._import_hardware_context(c_test_run, s_test_run)
-        self._log('hardware')
-        self._import_software_context(c_test_run, s_test_run)
-        self._log('software')
-        self._import_attributes(c_test_run, s_test_run)
-        self._log('attributes')
-        # collect all the changes that happen before the previous save
-        s_test_run.save()
-        s_test_run.denormalize()
-        return s_test_run
-
-    def _import_software_context(self, c_test_run, s_test_run):
-        """
-        Import software context.
-
-        In format 1.0 that's just a list of packages and software image
-        description
-        """
-        self._import_packages(c_test_run, s_test_run)
-        s_test_run.sw_image_desc = self._get_sw_context(c_test_run).get(
-                "sw_image", {}).get("desc", "")
-
-    def _import_hardware_context(self, c_test_run, s_test_run):
-        """
-        Import hardware context.
-
-        In format 1.0 that's just a list of devices
-        """
-        self._import_devices(c_test_run, s_test_run)
-
-    def _import_test(self, c_test_run):
-        """
-        Import dashboard_app.models.Test into the database
-        based on a client-side description of a TestRun
-        """
-        from dashboard_app.models import Test
-
-        s_test, test_created = Test.objects.get_or_create(
-            test_id = c_test_run["test_id"]) # required by schema
-        if test_created:
-            s_test.save()
-        return s_test
-
-    def _import_test_results_sqlite(self, c_test_results, s_test_run):
-        cursor = connection.cursor()
-
-        # XXX I don't understand how the _order column that Django adds is
-        # supposed to work.  I just set it to 0 here.
-
-        data = []
-
-        for index, c_test_result in enumerate(c_test_results, 1):
-
-            timestamp = c_test_result.get("timestamp")
-            if timestamp:
-                timestamp = datetime_extension.from_json(timestamp)
-            duration = c_test_result.get("duration", None)
-            if duration:
-                duration = timedelta_extension.from_json(duration)
-                duration = (duration.microseconds +
-                            (duration.seconds * 10 ** 6) +
-                            (duration.days * 24 * 60 * 60 * 10 ** 6))
-            result = self._translate_result_string(c_test_result["result"])
-
-            data.append((
-                s_test_run.id,
-                index,
-                timestamp,
-                duration,
-                c_test_result.get("log_filename", None),
-                result,
-                c_test_result.get("measurement", None),
-                c_test_result.get("message", None),
-                c_test_result.get("log_lineno", None),
-                s_test_run.test.id,
-                c_test_result.get("test_case_id", None),
-                ))
-
-        cursor.executemany(
-            """
-            INSERT INTO dashboard_app_testresult (
-                test_run_id,
-                relative_index,
-                timestamp,
-                microseconds,
-                filename,
-                result,
-                measurement,
-                message,
-                lineno,
-                _order,
-                test_case_id
-            ) select
-                %s,
-                %s,
-                %s,
-                %s,
-                %s,
-                %s,
-                %s,
-                %s,
-                %s,
-                0,
-                dashboard_app_testcase.id
-                FROM dashboard_app_testcase
-                  WHERE dashboard_app_testcase.test_id = %s
-                    AND dashboard_app_testcase.test_case_id
-                      = %s
-            """, data)
-
-        cursor.close()
-
-    def _import_test_results_pgsql(self, c_test_results, s_test_run):
-        cursor = connection.cursor()
-
-        # XXX I don't understand how the _order column that Django adds is
-        # supposed to work.  I just let it default to 0 here.
-
-        data = []
-
-        for i in range(0, len(c_test_results), 1000):
-
-            cursor.execute(
-                """
-                CREATE TEMPORARY TABLE newtestresults (
-                    relative_index INTEGER,
-                    timestamp      TIMESTAMP WITH TIME ZONE,
-                    microseconds   BIGINT,
-                    filename       TEXT,
-                    result         SMALLINT,
-                    measurement    NUMERIC(20,10),
-                    message        TEXT,
-                    test_case_id   TEXT,
-                    lineno         INTEGER
-                    )
-                """)
-
-            data = []
-
-            for index, c_test_result in enumerate(c_test_results[i:i+1000], i+1):
-
-                timestamp = c_test_result.get("timestamp")
-                if timestamp:
-                    timestamp = datetime_extension.from_json(timestamp)
-                duration = c_test_result.get("duration", None)
-                if duration:
-                    duration = timedelta_extension.from_json(duration)
-                    duration = (duration.microseconds +
-                                (duration.seconds * 10 ** 6) +
-                                (duration.days * 24 * 60 * 60 * 10 ** 6))
-                result = self._translate_result_string(c_test_result["result"])
-
-                data.extend([
-                    index,
-                    timestamp,
-                    duration,
-                    c_test_result.get("log_filename", None),
-                    result,
-                    c_test_result.get("measurement", None),
-                    c_test_result.get("message", None),
-                    c_test_result.get("test_case_id", None),
-                    c_test_result.get("log_lineno", None),
-                    ])
-
-            sequel = ',\n'.join(
-                ["(" + "%s" % (', '.join(['%s']*9),) + ")"] * (len(data) // 9))
-
-            cursor.execute(
-                """
-                INSERT INTO newtestresults (
-                    relative_index,
-                    timestamp,
-                    microseconds,
-                    filename,
-                    result,
-                    measurement,
-                    message,
-                    test_case_id,
-                    lineno
-                ) VALUES """ + sequel, data)
-
-            cursor.execute(
-                """
-                INSERT INTO dashboard_app_testresult (
-                    test_run_id,
-                    relative_index,
-                    timestamp,
-                    microseconds,
-                    filename,
-                    result,
-                    measurement,
-                    message,
-                    test_case_id,
-                    lineno
-                ) SELECT
-                    %s,
-                    relative_index,
-                    timestamp,
-                    microseconds,
-                    filename,
-                    result,
-                    measurement,
-                    message,
-                    dashboard_app_testcase.id,
-                    lineno
-                    FROM newtestresults, dashboard_app_testcase
-                      WHERE dashboard_app_testcase.test_id = %s
-                        AND dashboard_app_testcase.test_case_id
-                          = newtestresults.test_case_id
-                """ % (s_test_run.id, s_test_run.test.id))
-
-            cursor.execute(
-                """
-                DROP TABLE newtestresults
-                """)
-
-        cursor.close()
-
-    def _import_test_results(self, c_test_run, s_test_run):
-        """
-        Import TestRun.test_results
-        """
-        from dashboard_app.models import TestResult
-
-        c_test_results = c_test_run.get("test_results", [])
-
-        if not c_test_results:
-            return
-
-        if is_postgres():
-            self._import_test_cases_pgsql(c_test_results, s_test_run.test)
-        else:
-            self._import_test_cases_sqlite(c_test_results, s_test_run.test)
-
-        if is_postgres():
-            self._import_test_results_pgsql(c_test_results, s_test_run)
-        else:
-            self._import_test_results_sqlite(c_test_results, s_test_run)
-
-        for index, c_test_result in enumerate(c_test_run.get("test_results", []), 1):
-            if c_test_result.get("attributes", {}):
-                s_test_result = TestResult.objects.get(
-                    relative_index=index, test_run=s_test_run)
-                self._import_attributes(c_test_result, s_test_result)
-        self._log('test result attributes')
-
-    def _import_test_cases_sqlite(self, c_test_results, s_test):
-        """
-        Import TestCase
-        """
-        id_units = []
-        for c_test_result in c_test_results:
-            if "test_case_id" not in c_test_result:
-                continue
-            id_units.append(
-                (c_test_result["test_case_id"],
-                 c_test_result.get("units", "")))
-
-        cursor = connection.cursor()
-
-        data = []
-        for (test_case_id, units) in id_units:
-            data.append((s_test.id, units, test_case_id))
-        cursor.executemany(
-            """
-            INSERT OR IGNORE INTO
-                dashboard_app_testcase (test_id, units, name, test_case_id)
-            VALUES (%s, %s, '', %s)
-            """, data)
-        cursor.close()
-
-    def _import_test_cases_pgsql(self, c_test_results, s_test):
-        """
-        Import TestCase
-        """
-        id_units = {}
-        for c_test_result in c_test_results:
-            if "test_case_id" not in c_test_result:
-                continue
-            id_units.setdefault(
-                c_test_result["test_case_id"], c_test_result.get("units", ""))
-        id_units = id_units.items()
-
-        cursor = connection.cursor()
-        for i in range(0, len(id_units), 1000):
-
-            cursor.execute(
-                """
-                CREATE TEMPORARY TABLE
-                    newtestcases (test_case_id text, units text)
-                """)
-            data = []
-            for (id, units) in id_units[i:i+1000]:
-                data.append(id)
-                data.append(units)
-            sequel = ',\n'.join(["(%s, %s)"] * (len(data) // 2))
-            cursor.execute(
-                """
-                INSERT INTO newtestcases (test_case_id, units) VALUES
-                """ + sequel, data)
-
-            cursor.execute(
-                """
-                INSERT INTO
-                    dashboard_app_testcase (test_id, units, name, test_case_id)
-                SELECT %s, units, E'', test_case_id FROM newtestcases
-                WHERE NOT EXISTS (SELECT 1 FROM dashboard_app_testcase
-                                  WHERE test_id = %s
-                                    AND newtestcases.test_case_id
-                                      = dashboard_app_testcase.test_case_id)
-                """ % (s_test.id, s_test.id))
-            cursor.execute(
-                """
-                drop table newtestcases
-                """)
-        cursor.close()
-
-    def _import_packages_scratch_sqlite(self, cursor, packages):
-        data = []
-        for c_package in packages:
-            data.append((c_package['name'], c_package['version']))
-        cursor.executemany(
-            """
-            INSERT INTO dashboard_app_softwarepackagescratch
-                   (name, version) VALUES (%s, %s)
-            """, data)
-
-    def _import_packages_scratch_pgsql(self, cursor, packages):
-        for i in range(0, len(packages), 1000):
-            data = []
-            for c_package in packages[i:i+1000]:
-                data.append(c_package['name'])
-                data.append(c_package['version'])
-            sequel = ', '.join(["(%s, %s)"] * (len(data) // 2))
-            cursor.execute(
-                "INSERT INTO dashboard_app_softwarepackagescratch (name, version) VALUES " + sequel, data)
-
-    def _import_packages(self, c_test_run, s_test_run):
-        """
-        Import TestRun.pacakges
-        """
-        packages = self._get_sw_context(c_test_run).get("packages", [])
-        if not packages:
-            return
-        cursor = connection.cursor()
-
-        if is_postgres():
-            self._import_packages_scratch_pgsql(cursor, packages)
-        else:
-            self._import_packages_scratch_sqlite(cursor, packages)
-
-        cursor.execute(
-            """
-            INSERT INTO dashboard_app_softwarepackage (name, version)
-            SELECT name, version FROM dashboard_app_softwarepackagescratch
-            EXCEPT SELECT name, version FROM dashboard_app_softwarepackage
-            """)
-        cursor.execute(
-            """
-            INSERT INTO
-                dashboard_app_testrun_packages (testrun_id, softwarepackage_id)
-            SELECT %s, id FROM dashboard_app_softwarepackage
-                WHERE EXISTS (
-                    SELECT * FROM dashboard_app_softwarepackagescratch
-                        WHERE dashboard_app_softwarepackage.name
-                            = dashboard_app_softwarepackagescratch.name
-                          AND dashboard_app_softwarepackage.version
-                            = dashboard_app_softwarepackagescratch.version)
-            """ % s_test_run.id)
-        cursor.execute(
-            """
-            delete from dashboard_app_softwarepackagescratch
-            """)
-        cursor.close()
-
-    def _import_devices(self, c_test_run, s_test_run):
-        """
-        Import TestRun.devices
-        """
-        from dashboard_app.models import HardwareDevice
-
-        for c_device in self._get_hw_context(c_test_run).get("devices", []):
-            s_device = HardwareDevice.objects.create(
-                device_type = c_device["device_type"],
-                description = c_device["description"]
-            )
-            s_device.save()
-            self._import_attributes(c_device, s_device)
-            s_test_run.devices.add(s_device)
-
-    def _import_attributes(self, c_object, s_object):
-        """
-        Import attributes from any client-side object into any
-        server-side object
-        """
-        for name, value in c_object.get("attributes", {}).iteritems():
-            s_object.attributes.create(
-                name=str(name), value=str(value))
-
-    def _import_attachments(self, c_test_run, s_test_run):
-        """
-        Import TestRun.attachments
-        """
-        for filename, lines in c_test_run.get("attachments", {}).iteritems():
-            s_attachment = s_test_run.attachments.create(
-                mime_type="text/plain",
-                content_filename=filename)
-            s_attachment.save()
-            s_attachment.content.save(
-                "attachment-{0}.txt".format(s_attachment.pk),
-                ContentFile("".join(lines).encode("UTF-8")))
-            # Collect this attachment for cleanup in case something goes wrong
-            # and we need to rollback the transaction
-            self._content_files.append(s_attachment)
-
-    def _translate_result_string(self, result):
-        """
-        Translate result string used by client-side API to our internal
-        database integer representing the same value.
-        """
-        from dashboard_app.models import TestResult
-        return {
-            "pass": TestResult.RESULT_PASS,
-            "fail": TestResult.RESULT_FAIL,
-            "skip": TestResult.RESULT_SKIP,
-            "unknown": TestResult.RESULT_UNKNOWN
-        }[result]
-
-    def _get_sw_context(self, c_test_run):
-        return c_test_run.get("sw_context", {})
-
-    def _get_hw_context(self, c_test_run):
-        return c_test_run.get("hw_context", {})
-
-
-class BundleFormatImporter_1_0_1(BundleFormatImporter_1_0):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.0.1"
-    """
-
-    def _get_sw_context(self, c_test_run):
-        return c_test_run.get("software_context", {})
-
-    def _get_hw_context(self, c_test_run):
-        return c_test_run.get("hardware_context", {})
-
-
-class BundleFormatImporter_1_1(BundleFormatImporter_1_0_1):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.1"
-    """
-
-    def _import_software_context(self, c_test_run, s_test_run):
-        """
-        Import software context in 1.1 format.
-
-        Note: We're not upcalling super here as the second line importing
-        software image name is quite different in the previous format and I did
-        not want to create another function for that. Copying the frozen
-        implementation from previous format is IMHO cleaner.
-        """
-        self._import_packages(c_test_run, s_test_run)
-        s_test_run.sw_image_desc = self._get_sw_context(c_test_run).get(
-                "image", {}).get("name", "")
-        self._import_sources(c_test_run, s_test_run)
-
-    def _import_attachments(self, c_test_run, s_test_run):
-        """
-        Import TestRun.attachments
-        """
-        for c_attachment in c_test_run.get("attachments", []):
-            s_attachment = s_test_run.attachments.create(
-                content_filename = c_attachment["pathname"],
-                mime_type = c_attachment["mime_type"])
-            # Save to get pk
-            s_attachment.save()
-            content = base64.standard_b64decode(c_attachment["content"])
-            s_attachment.content.save(
-                "attachment-{0}.txt".format(s_attachment.pk),
-                ContentFile(content))
-
-    def _import_sources(self, c_test_run, s_test_run):
-        """
-        Import TestRun.sources
-        """
-        from dashboard_app.models import SoftwareSource
-
-        for c_source in self._get_sw_context(c_test_run).get("sources", []):
-            s_source, source_created = SoftwareSource.objects.get_or_create(
-                project_name = c_source["project_name"], # required by schema
-                branch_url = c_source["branch_url"], # required by schema
-                branch_vcs = c_source["branch_vcs"], # required by schema
-                # required by schema, may be either int or string so upconvert to string
-                branch_revision = str(c_source["branch_revision"]),
-                # optional
-                commit_timestamp = (
-                    datetime_extension.from_json(
-                        c_source["commit_timestamp"])
-                    if "commit_timestamp" in c_source
-                    else None)
-            )
-            if source_created:
-                s_source.save()
-            s_test_run.sources.add(s_source)
-
-
-class BundleFormatImporter_1_2(BundleFormatImporter_1_1):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.2"
-    """
-
-    def _import_attachments(self, c_test_run, s_test_run):
-        """
-        Import TestRun.attachments
-        """
-        for c_attachment in c_test_run.get("attachments", []):
-            s_attachment = s_test_run.attachments.create(
-                content_filename = c_attachment["pathname"],
-                public_url = c_attachment.get("public_url", ""),
-                mime_type = c_attachment["mime_type"])
-            s_attachment.save()
-            if "content" in c_attachment:
-                # Content is optional now
-                content = base64.standard_b64decode(c_attachment["content"])
-                s_attachment.content.save(
-                    "attachment-{0}.txt".format(s_attachment.pk),
-                    ContentFile(content))
-
-
-class BundleFormatImporter_1_3(BundleFormatImporter_1_2):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.3"
-    """
-
-    def _import_test_run(self, c_test_run, s_bundle):
-        from dashboard_app.models import Tag
-
-        s_test_run = super(BundleFormatImporter_1_3, self)._import_test_run(c_test_run, s_bundle)
-        self._log('tags')
-        for c_tag in c_test_run.get("tags", []):
-            s_tag, created = Tag.objects.get_or_create(name=c_tag)
-            if created:
-                s_tag.save()
-            s_test_run.tags.add(s_tag)
-        return s_test_run
-
-
-class BundleFormatImporter_1_4(BundleFormatImporter_1_3):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.4"
-    """
-
-    def _import_test_run(self, c_test_run, s_bundle):
-        s_test_run = super(BundleFormatImporter_1_4, self)._import_test_run(c_test_run, s_bundle)
-        test_duration = c_test_run.get('test_duration')
-        if test_duration is not None:
-            test_duration = timedelta_extension.from_json(test_duration)
-            s_test_run.test_duration = test_duration
-            s_test_run.save()
-        return s_test_run
-
-
-class BundleFormatImporter_1_5(BundleFormatImporter_1_4):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.5"
-    """
-
-    def _import_test_result_attachments(self, c_test_result, s_test_result):
-        for c_attachment in c_test_result.get("attachments", []):
-            s_attachment = s_test_result.attachments.create(
-                content_filename = c_attachment["pathname"],
-                mime_type = c_attachment["mime_type"])
-            # Save to get pk
-            s_attachment.save()
-            content = base64.standard_b64decode(c_attachment["content"])
-            s_attachment.content.save(
-                "attachment-{0}.txt".format(s_attachment.pk),
-                ContentFile(content))
-
-    def _import_test_results(self, c_test_run, s_test_run):
-        from dashboard_app.models import TestResult
-        super(BundleFormatImporter_1_5, self)._import_test_results(c_test_run, s_test_run)
-        for index, c_test_result in enumerate(c_test_run.get("test_results", []), 1):
-            if c_test_result.get("attachments", {}):
-                s_test_result = TestResult.objects.get(
-                    relative_index=index, test_run=s_test_run)
-                self._import_test_result_attachments(c_test_result, s_test_result)
-
-
-class BundleFormatImporter_1_6(BundleFormatImporter_1_5):
-    """
-    IFormatImporter subclass capable of loading "Dashboard Bundle Format 1.6"
-    """
-
-    def _import_testdef(self, c_test_id, c_testdef_metadata):
-        """
-        Import dashboard_app.models.TestDefinition into the database
-        based on a client-side description of a TestRun metadata.
-        """
-        from dashboard_app.models import TestDefinition
-
-        testdef_meta = {
-            'name': c_test_id,
-            'version': c_testdef_metadata.get("version"),
-            'description': c_testdef_metadata.get("description"),
-            'format': c_testdef_metadata.get("format"),
-            'location': c_testdef_metadata.get("location"),
-            'url': c_testdef_metadata.get("url"),
-            'environment': c_testdef_metadata.get("environment"),
-            'target_os': c_testdef_metadata.get("os"),
-            'target_dev_types': c_testdef_metadata.get("devices"),
-            }
-
-        try:
-            s_testdef = TestDefinition.objects.get(name=c_test_id)
-            # Do not try to update name since it is unique, hence
-            # pop it from the dictionary.
-            testdef_meta.pop('name', None)
-            TestDefinition.objects.filter(name=c_test_id).update(
-                **testdef_meta)
-        except ObjectDoesNotExist:
-            s_testdef = TestDefinition.objects.create(**testdef_meta)
-            s_testdef.save()
-
-    def _import_test_results(self, c_test_run, s_test_run):
-        from dashboard_app.models import TestResult
-        super(BundleFormatImporter_1_6, self)._import_test_results(c_test_run,
-                                                                   s_test_run)
-        if c_test_run.get("testdef_metadata"):
-            self._import_testdef(c_test_run["test_id"],
-                                 c_test_run["testdef_metadata"])
-
-
-class BundleDeserializer(object):
-    """
-    Helper class for de-serializing JSON bundle content into database models
-    """
-
-    IMPORTERS = {
-        "Dashboard Bundle Format 1.0": BundleFormatImporter_1_0,
-        "Dashboard Bundle Format 1.0.1": BundleFormatImporter_1_0_1,
-        "Dashboard Bundle Format 1.1": BundleFormatImporter_1_1,
-        "Dashboard Bundle Format 1.2": BundleFormatImporter_1_2,
-        "Dashboard Bundle Format 1.3": BundleFormatImporter_1_3,
-        "Dashboard Bundle Format 1.4": BundleFormatImporter_1_4,
-        "Dashboard Bundle Format 1.5": BundleFormatImporter_1_5,
-        "Dashboard Bundle Format 1.6": BundleFormatImporter_1_6,
-    }
-
-    def deserialize(self, s_bundle, prefer_evolution):
-        """
-        Deserializes specified Bundle.
-
-        :Discussion:
-            This method also handles internal transaction handling.
-            All operations performed during bundle deserialization are
-            _rolled_back_ if anything fails.
-
-            If prefer_evolution is enabled then the document is first evolved
-            to the latest known format and only then imported into the
-            database. This operation is currently disabled to ensure that all
-            old documents are imported exactly as before. Enabling it should
-            be quite safe though as it passes all tests.
-
-        :Exceptions raised:
-            json_schema_validator.ValidationError
-                When the document does not match the appropriate schema.
-            linaro_dashboard_bundle.errors.DocumentFormatError
-                When the document format is not in the known set of formats.
-            ValueError
-                When the text does not represent a correct JSON document.
-        """
-        assert s_bundle.is_deserialized is False
-        s_bundle.content.open('rb')
-        try:
-            logging.debug("Loading document")
-            fmt, doc = DocumentIO.load(s_bundle.content)
-            logging.debug("Document loaded")
-            if prefer_evolution:
-                logging.debug("Evolving document")
-                DocumentEvolution.evolve_document(doc)
-                logging.debug("Document evolution complete")
-                fmt = doc["format"]
-        finally:
-            s_bundle.content.close()
-        importer = self.IMPORTERS.get(fmt)
-        if importer is None:
-            raise DocumentFormatError(fmt)
-        try:
-            logging.debug("Importing document")
-            importer().import_document(s_bundle, doc)
-            logging.debug("Document import complete")
-        except Exception as exc:
-            logging.debug("Exception while importing document: %r", exc)
-            raise

=== removed file 'dashboard_app/managers.py'
--- dashboard_app/managers.py	2011-09-28 02:28:43 +0000
+++ dashboard_app/managers.py	1970-01-01 00:00:00 +0000
@@ -1,70 +0,0 @@
-# Copyright (C) 2010, 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-#
-from django.core.files.base import ContentFile
-from django.db import models, transaction, IntegrityError
-
-import logging
-
-
-class BundleManager(models.Manager):
-
-    @transaction.commit_on_success
-    def create_with_content(self, bundle_stream, uploaded_by, content_filename, content):
-        logging.debug("Creating bundle object")
-        bundle = self.create(
-                bundle_stream=bundle_stream,
-                uploaded_by=uploaded_by,
-                content_filename=content_filename)
-        # XXX: this _can_ fail -- if content_sha1 is a duplicate
-        logging.debug("Saving bundle object (this is safe so far)")
-        bundle.save()
-        try:
-            logging.debug("saving bundle content (file) and bundle object")
-            bundle.content.save("bundle-{0}".format(bundle.pk),
-                                ContentFile(content))
-        except IntegrityError as exc:
-            logging.debug("integrity error: %r", exc)
-            # Note: we're not saving the deletion back to the database
-            # because we are going to rollback anyway. In PostgreSQL this
-            # would also always fail because the database is not going to
-            # honor any other operations until we rollback.
-            # See: 
-            # http://docs.djangoproject.com/en/1.2/topics/db/transactions/#handling-exceptions-within-postgresql-transactions
-            logging.debug("deleting content file")
-            bundle.content.delete(save=False)
-            raise
-        else:
-            return bundle 
-
-
-class TestRunDenormalizationManager(models.Manager):
-
-    def create_from_test_run(self, test_run):
-        from dashboard_app.models import TestResult
-        stats = test_run.test_results.values('result').annotate(
-            count=models.Count('result')).order_by()
-        result = dict([
-            (TestResult.RESULT_MAP[item['result']], item['count'])
-            for item in stats])
-        return self.create(
-            test_run=test_run,
-            count_pass=result.get('pass', 0),
-            count_fail=result.get('fail', 0),
-            count_skip=result.get('skip', 0),
-            count_unknown=result.get('unknown', 0))

=== removed directory 'dashboard_app/migrations'
=== removed file 'dashboard_app/migrations/0001_initial.py'
--- dashboard_app/migrations/0001_initial.py	2011-04-18 10:24:59 +0000
+++ dashboard_app/migrations/0001_initial.py	1970-01-01 00:00:00 +0000
@@ -1,382 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-    
-    def forwards(self, orm):
-        
-        # Adding model 'SoftwarePackage'
-        db.create_table('dashboard_app_softwarepackage', (
-            ('version', self.gf('django.db.models.fields.CharField')(max_length=64)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
-        ))
-        db.send_create_signal('dashboard_app', ['SoftwarePackage'])
-
-        # Adding unique constraint on 'SoftwarePackage', fields ['name', 'version']
-        db.create_unique('dashboard_app_softwarepackage', ['name', 'version'])
-
-        # Adding model 'NamedAttribute'
-        db.create_table('dashboard_app_namedattribute', (
-            ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
-            ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('value', self.gf('django.db.models.fields.CharField')(max_length=512)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=32)),
-        ))
-        db.send_create_signal('dashboard_app', ['NamedAttribute'])
-
-        # Adding unique constraint on 'NamedAttribute', fields ['object_id', 'name']
-        db.create_unique('dashboard_app_namedattribute', ['object_id', 'name'])
-
-        # Adding model 'HardwareDevice'
-        db.create_table('dashboard_app_hardwaredevice', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('device_type', self.gf('django.db.models.fields.CharField')(max_length=32)),
-            ('description', self.gf('django.db.models.fields.CharField')(max_length=256)),
-        ))
-        db.send_create_signal('dashboard_app', ['HardwareDevice'])
-
-        # Adding model 'BundleStream'
-        db.create_table('dashboard_app_bundlestream', (
-            ('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.Group'], null=True, blank=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)),
-            ('is_anonymous', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('pathname', self.gf('django.db.models.fields.CharField')(unique=True, max_length=128)),
-            ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True)),
-            ('is_public', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
-            ('slug', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['BundleStream'])
-
-        # Adding model 'Bundle'
-        db.create_table('dashboard_app_bundle', (
-            ('content_sha1', self.gf('django.db.models.fields.CharField')(max_length=40, unique=True, null=True)),
-            ('bundle_stream', self.gf('django.db.models.fields.related.ForeignKey')(related_name='bundles', to=orm['dashboard_app.BundleStream'])),
-            ('uploaded_on', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.utcnow)),
-            ('content', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True)),
-            ('uploaded_by', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='uploaded_bundles', null=True, to=orm['auth.User'])),
-            ('content_filename', self.gf('django.db.models.fields.CharField')(max_length=256)),
-            ('is_deserialized', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['Bundle'])
-
-        # Adding model 'BundleDeserializationError'
-        db.create_table('dashboard_app_bundledeserializationerror', (
-            ('error_message', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('bundle', self.gf('django.db.models.fields.related.ForeignKey')(related_name='deserialization_error', unique=True, primary_key=True, to=orm['dashboard_app.Bundle'])),
-            ('traceback', self.gf('django.db.models.fields.TextField')(max_length=32768)),
-        ))
-        db.send_create_signal('dashboard_app', ['BundleDeserializationError'])
-
-        # Adding model 'Test'
-        db.create_table('dashboard_app_test', (
-            ('test_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=64)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=64, blank=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['Test'])
-
-        # Adding model 'TestCase'
-        db.create_table('dashboard_app_testcase', (
-            ('test', self.gf('django.db.models.fields.related.ForeignKey')(related_name='test_cases', to=orm['dashboard_app.Test'])),
-            ('units', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
-            ('test_case_id', self.gf('django.db.models.fields.CharField')(max_length=100)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestCase'])
-
-        # Adding unique constraint on 'TestCase', fields ['test', 'test_case_id']
-        db.create_unique('dashboard_app_testcase', ['test_id', 'test_case_id'])
-
-        # Adding model 'SoftwareSource'
-        db.create_table('dashboard_app_softwaresource', (
-            ('project_name', self.gf('django.db.models.fields.CharField')(max_length=32)),
-            ('branch_url', self.gf('django.db.models.fields.CharField')(max_length=256)),
-            ('branch_vcs', self.gf('django.db.models.fields.CharField')(max_length=10)),
-            ('commit_timestamp', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('branch_revision', self.gf('django.db.models.fields.CharField')(max_length=128)),
-        ))
-        db.send_create_signal('dashboard_app', ['SoftwareSource'])
-
-        # Adding model 'TestRun'
-        db.create_table('dashboard_app_testrun', (
-            ('sw_image_desc', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)),
-            ('analyzer_assigned_date', self.gf('django.db.models.fields.DateTimeField')()),
-            ('bundle', self.gf('django.db.models.fields.related.ForeignKey')(related_name='test_runs', to=orm['dashboard_app.Bundle'])),
-            ('time_check_performed', self.gf('django.db.models.fields.BooleanField')(default=False, blank=True)),
-            ('analyzer_assigned_uuid', self.gf('django.db.models.fields.CharField')(unique=True, max_length=36)),
-            ('test', self.gf('django.db.models.fields.related.ForeignKey')(related_name='test_runs', to=orm['dashboard_app.Test'])),
-            ('import_assigned_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRun'])
-
-        # Adding M2M table for field sources on 'TestRun'
-        db.create_table('dashboard_app_testrun_sources', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testrun', models.ForeignKey(orm['dashboard_app.testrun'], null=False)),
-            ('softwaresource', models.ForeignKey(orm['dashboard_app.softwaresource'], null=False))
-        ))
-        db.create_unique('dashboard_app_testrun_sources', ['testrun_id', 'softwaresource_id'])
-
-        # Adding M2M table for field packages on 'TestRun'
-        db.create_table('dashboard_app_testrun_packages', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testrun', models.ForeignKey(orm['dashboard_app.testrun'], null=False)),
-            ('softwarepackage', models.ForeignKey(orm['dashboard_app.softwarepackage'], null=False))
-        ))
-        db.create_unique('dashboard_app_testrun_packages', ['testrun_id', 'softwarepackage_id'])
-
-        # Adding M2M table for field devices on 'TestRun'
-        db.create_table('dashboard_app_testrun_devices', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testrun', models.ForeignKey(orm['dashboard_app.testrun'], null=False)),
-            ('hardwaredevice', models.ForeignKey(orm['dashboard_app.hardwaredevice'], null=False))
-        ))
-        db.create_unique('dashboard_app_testrun_devices', ['testrun_id', 'hardwaredevice_id'])
-
-        # Adding model 'Attachment'
-        db.create_table('dashboard_app_attachment', (
-            ('content_filename', self.gf('django.db.models.fields.CharField')(max_length=256)),
-            ('public_url', self.gf('django.db.models.fields.URLField')(max_length=512, blank=True)),
-            ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()),
-            ('content', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True)),
-            ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('mime_type', self.gf('django.db.models.fields.CharField')(max_length=64)),
-        ))
-        db.send_create_signal('dashboard_app', ['Attachment'])
-
-        # Adding model 'TestResult'
-        db.create_table('dashboard_app_testresult', (
-            ('test_run', self.gf('django.db.models.fields.related.ForeignKey')(related_name='test_results', to=orm['dashboard_app.TestRun'])),
-            ('_order', self.gf('django.db.models.fields.IntegerField')(default=0)),
-            ('relative_index', self.gf('django.db.models.fields.PositiveIntegerField')()),
-            ('timestamp', self.gf('django.db.models.fields.DateTimeField')(null=True, blank=True)),
-            ('microseconds', self.gf('django.db.models.fields.BigIntegerField')(null=True, blank=True)),
-            ('filename', self.gf('django.db.models.fields.CharField')(max_length=1024, null=True, blank=True)),
-            ('result', self.gf('django.db.models.fields.PositiveSmallIntegerField')()),
-            ('measurement', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=20, decimal_places=10, blank=True)),
-            ('message', self.gf('django.db.models.fields.TextField')(max_length=1024, null=True, blank=True)),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('test_case', self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='test_results', null=True, to=orm['dashboard_app.TestCase'])),
-            ('lineno', self.gf('django.db.models.fields.PositiveIntegerField')(null=True, blank=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestResult'])
-    
-    
-    def backwards(self, orm):
-        
-        # Deleting model 'SoftwarePackage'
-        db.delete_table('dashboard_app_softwarepackage')
-
-        # Removing unique constraint on 'SoftwarePackage', fields ['name', 'version']
-        db.delete_unique('dashboard_app_softwarepackage', ['name', 'version'])
-
-        # Deleting model 'NamedAttribute'
-        db.delete_table('dashboard_app_namedattribute')
-
-        # Removing unique constraint on 'NamedAttribute', fields ['object_id', 'name']
-        db.delete_unique('dashboard_app_namedattribute', ['object_id', 'name'])
-
-        # Deleting model 'HardwareDevice'
-        db.delete_table('dashboard_app_hardwaredevice')
-
-        # Deleting model 'BundleStream'
-        db.delete_table('dashboard_app_bundlestream')
-
-        # Deleting model 'Bundle'
-        db.delete_table('dashboard_app_bundle')
-
-        # Deleting model 'BundleDeserializationError'
-        db.delete_table('dashboard_app_bundledeserializationerror')
-
-        # Deleting model 'Test'
-        db.delete_table('dashboard_app_test')
-
-        # Deleting model 'TestCase'
-        db.delete_table('dashboard_app_testcase')
-
-        # Removing unique constraint on 'TestCase', fields ['test', 'test_case_id']
-        db.delete_unique('dashboard_app_testcase', ['test_id', 'test_case_id'])
-
-        # Deleting model 'SoftwareSource'
-        db.delete_table('dashboard_app_softwaresource')
-
-        # Deleting model 'TestRun'
-        db.delete_table('dashboard_app_testrun')
-
-        # Removing M2M table for field sources on 'TestRun'
-        db.delete_table('dashboard_app_testrun_sources')
-
-        # Removing M2M table for field packages on 'TestRun'
-        db.delete_table('dashboard_app_testrun_packages')
-
-        # Removing M2M table for field devices on 'TestRun'
-        db.delete_table('dashboard_app_testrun_devices')
-
-        # Deleting model 'Attachment'
-        db.delete_table('dashboard_app_attachment')
-
-        # Deleting model 'TestResult'
-        db.delete_table('dashboard_app_testresult')
-    
-    
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'blank': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'blank': 'True'})
-        }
-    }
-    
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0002_add_index_NamedAttribute_object_id_and_content_type_id_and_name.py'
--- dashboard_app/migrations/0002_add_index_NamedAttribute_object_id_and_content_type_id_and_name.py	2011-05-02 17:47:00 +0000
+++ dashboard_app/migrations/0002_add_index_NamedAttribute_object_id_and_content_type_id_and_name.py	1970-01-01 00:00:00 +0000
@@ -1,170 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Adding index on 'NamedAttribute', fields ['object_id', 'content_type_id', 'name']
-        db.create_index('dashboard_app_namedattribute', ['object_id', 'content_type_id', 'name'])
-
-
-    def backwards(self, orm):
-        
-        # Removing index on 'NamedAttribute', fields ['object_id', 'content_type_id', 'name']
-        db.delete_index('dashboard_app_namedattribute', ['object_id', 'content_type-id', 'name'])
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0003_add_index_HardwareDevice_device_type.py'
--- dashboard_app/migrations/0003_add_index_HardwareDevice_device_type.py	2011-05-02 17:47:00 +0000
+++ dashboard_app/migrations/0003_add_index_HardwareDevice_device_type.py	1970-01-01 00:00:00 +0000
@@ -1,170 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Adding index on 'HardwareDevice', fields ['device_type', 'id']
-        db.create_index('dashboard_app_hardwaredevice', ['device_type', 'id'])
-
-
-    def backwards(self, orm):
-        
-        # Removing index on 'HardwareDevice', fields ['device_type', 'id']
-        db.delete_index('dashboard_app_hardwaredevice', ['device_type', 'id'])
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0004_auto__add_softwarepackagescratch.py'
--- dashboard_app/migrations/0004_auto__add_softwarepackagescratch.py	2011-07-04 02:09:01 +0000
+++ dashboard_app/migrations/0004_auto__add_softwarepackagescratch.py	1970-01-01 00:00:00 +0000
@@ -1,181 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Adding model 'SoftwarePackageScratch'
-        db.create_table('dashboard_app_softwarepackagescratch', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=64)),
-            ('version', self.gf('django.db.models.fields.CharField')(max_length=64)),
-        ))
-        db.send_create_signal('dashboard_app', ['SoftwarePackageScratch'])
-
-
-    def backwards(self, orm):
-        
-        # Deleting model 'SoftwarePackageScratch'
-        db.delete_table('dashboard_app_softwarepackagescratch')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '64'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0005_auto__chg_field_softwarepackage_version__chg_field_softwarepackage_nam.py'
--- dashboard_app/migrations/0005_auto__chg_field_softwarepackage_version__chg_field_softwarepackage_nam.py	2011-09-14 12:40:54 +0000
+++ dashboard_app/migrations/0005_auto__chg_field_softwarepackage_version__chg_field_softwarepackage_nam.py	1970-01-01 00:00:00 +0000
@@ -1,194 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Changing field 'SoftwarePackage.version'
-        db.alter_column('dashboard_app_softwarepackage', 'version', self.gf('django.db.models.fields.CharField')(max_length=128))
-
-        # Changing field 'SoftwarePackage.name'
-        db.alter_column('dashboard_app_softwarepackage', 'name', self.gf('django.db.models.fields.CharField')(max_length=128))
-
-        # Changing field 'SoftwarePackageScratch.version'
-        db.alter_column('dashboard_app_softwarepackagescratch', 'version', self.gf('django.db.models.fields.CharField')(max_length=128))
-
-        # Changing field 'SoftwarePackageScratch.name'
-        db.alter_column('dashboard_app_softwarepackagescratch', 'name', self.gf('django.db.models.fields.CharField')(max_length=128))
-
-
-    def backwards(self, orm):
-        
-        # Changing field 'SoftwarePackage.version'
-        db.alter_column('dashboard_app_softwarepackage', 'version', self.gf('django.db.models.fields.CharField')(max_length=64))
-
-        # Changing field 'SoftwarePackage.name'
-        db.alter_column('dashboard_app_softwarepackage', 'name', self.gf('django.db.models.fields.CharField')(max_length=64))
-
-        # Changing field 'SoftwarePackageScratch.version'
-        db.alter_column('dashboard_app_softwarepackagescratch', 'version', self.gf('django.db.models.fields.CharField')(max_length=64))
-
-        # Changing field 'SoftwarePackageScratch.name'
-        db.alter_column('dashboard_app_softwarepackagescratch', 'name', self.gf('django.db.models.fields.CharField')(max_length=64))
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0006_auto__chg_field_bundledeserializationerror_bundle.py'
--- dashboard_app/migrations/0006_auto__chg_field_bundledeserializationerror_bundle.py	2011-09-26 12:55:16 +0000
+++ dashboard_app/migrations/0006_auto__chg_field_bundledeserializationerror_bundle.py	1970-01-01 00:00:00 +0000
@@ -1,176 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Changing field 'BundleDeserializationError.bundle'
-        db.alter_column('dashboard_app_bundledeserializationerror', 'bundle_id', self.gf('django.db.models.fields.related.OneToOneField')(unique=True, primary_key=True, to=orm['dashboard_app.Bundle']))
-
-
-    def backwards(self, orm):
-        
-        # Changing field 'BundleDeserializationError.bundle'
-        db.alter_column('dashboard_app_bundledeserializationerror', 'bundle_id', self.gf('django.db.models.fields.related.ForeignKey')(unique=True, primary_key=True, to=orm['dashboard_app.Bundle']))
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0007_auto__add_tag.py'
--- dashboard_app/migrations/0007_auto__add_tag.py	2011-09-26 21:15:33 +0000
+++ dashboard_app/migrations/0007_auto__add_tag.py	1970-01-01 00:00:00 +0000
@@ -1,197 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Adding model 'Tag'
-        db.create_table('dashboard_app_tag', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=256, db_index=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['Tag'])
-
-        # Adding M2M table for field tags on 'TestRun'
-        db.create_table('dashboard_app_testrun_tags', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testrun', models.ForeignKey(orm['dashboard_app.testrun'], null=False)),
-            ('tag', models.ForeignKey(orm['dashboard_app.tag'], null=False))
-        ))
-        db.create_unique('dashboard_app_testrun_tags', ['testrun_id', 'tag_id'])
-
-
-    def backwards(self, orm):
-        
-        # Deleting model 'Tag'
-        db.delete_table('dashboard_app_tag')
-
-        # Removing M2M table for field tags on 'TestRun'
-        db.delete_table('dashboard_app_testrun_tags')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0008_auto__add_testingeffort.py'
--- dashboard_app/migrations/0008_auto__add_testingeffort.py	2013-01-15 21:04:42 +0000
+++ dashboard_app/migrations/0008_auto__add_testingeffort.py	1970-01-01 00:00:00 +0000
@@ -1,224 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    depends_on = (
-        ("lava_projects", "0001_add_model_Project"),
-    )
-
-    def forwards(self, orm):
-        
-        # Adding model 'TestingEffort'
-        db.create_table('dashboard_app_testingeffort', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='testing_efforts', to=orm['lava_projects.Project'])),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('description', self.gf('django.db.models.fields.TextField')()),
-        ))
-        db.send_create_signal('dashboard_app', ['TestingEffort'])
-
-        # Adding M2M table for field tags on 'TestingEffort'
-        db.create_table('dashboard_app_testingeffort_tags', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testingeffort', models.ForeignKey(orm['dashboard_app.testingeffort'], null=False)),
-            ('tag', models.ForeignKey(orm['dashboard_app.tag'], null=False))
-        ))
-        db.create_unique('dashboard_app_testingeffort_tags', ['testingeffort_id', 'tag_id'])
-
-
-    def backwards(self, orm):
-        
-        # Deleting model 'TestingEffort'
-        db.delete_table('dashboard_app_testingeffort')
-
-        # Removing M2M table for field tags on 'TestingEffort'
-        db.delete_table('dashboard_app_testingeffort_tags')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0009_auto__add_testrundenormalization.py'
--- dashboard_app/migrations/0009_auto__add_testrundenormalization.py	2011-09-28 02:28:43 +0000
+++ dashboard_app/migrations/0009_auto__add_testrundenormalization.py	1970-01-01 00:00:00 +0000
@@ -1,218 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Adding model 'TestRunDenormalization'
-        db.create_table('dashboard_app_testrundenormalization', (
-            ('test_run', self.gf('django.db.models.fields.related.OneToOneField')(related_name='denormalization', unique=True, primary_key=True, to=orm['dashboard_app.TestRun'])),
-            ('count_pass', self.gf('django.db.models.fields.PositiveIntegerField')()),
-            ('count_fail', self.gf('django.db.models.fields.PositiveIntegerField')()),
-            ('count_skip', self.gf('django.db.models.fields.PositiveIntegerField')()),
-            ('count_unknown', self.gf('django.db.models.fields.PositiveIntegerField')()),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRunDenormalization'])
-
-
-    def backwards(self, orm):
-        
-        # Deleting model 'TestRunDenormalization'
-        db.delete_table('dashboard_app_testrundenormalization')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0010_denormalize_test_run.py'
--- dashboard_app/migrations/0010_denormalize_test_run.py	2011-09-28 02:29:33 +0000
+++ dashboard_app/migrations/0010_denormalize_test_run.py	1970-01-01 00:00:00 +0000
@@ -1,235 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import DataMigration
-from django.db import models
-
-class Migration(DataMigration):
-
-    def forwards(self, orm):
-        # Result codes
-        RESULT_PASS = 0
-        RESULT_FAIL = 1
-        RESULT_SKIP = 2
-        RESULT_UNKNOWN = 3
-        # Code-to-name mapping
-        RESULT_MAP = {
-            RESULT_PASS: 'pass',
-            RESULT_FAIL: 'fail',
-            RESULT_SKIP: 'skip',
-            RESULT_UNKNOWN: 'unknown'
-        }
-        for test_run in orm.TestRun.objects.all():
-            stats = test_run.test_results.order_by(
-                # Disable sorting
-            ).values(
-                'result'  # only get the result outcome (pass/fail/etc)
-            ).annotate(
-                count=models.Count('result')  # Count number of items with this value
-            )
-            # Translate the 0-4 element array into a 0-4 element dictionary 
-            result = dict([
-                (RESULT_MAP[item['result']], item['count'])
-                for item in stats])
-            # Create a denormalized test run instance
-            orm.TestRunDenormalization.objects.create(
-                test_run=test_run,
-                count_pass=result.get('pass', 0),
-                count_fail=result.get('fail', 0),
-                count_skip=result.get('skip', 0),
-                count_unknown=result.get('unknown', 0))
-
-    def backwards(self, orm):
-        orm.TestRunDenormalization.objects.all().delete()
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '512'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0011_auto__chg_field_namedattribute_value__chg_field_namedattribute_name.py'
--- dashboard_app/migrations/0011_auto__chg_field_namedattribute_value__chg_field_namedattribute_name.py	2011-11-25 01:48:45 +0000
+++ dashboard_app/migrations/0011_auto__chg_field_namedattribute_value__chg_field_namedattribute_name.py	1970-01-01 00:00:00 +0000
@@ -1,217 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Changing field 'NamedAttribute.value'
-        db.alter_column('dashboard_app_namedattribute', 'value', self.gf('django.db.models.fields.TextField')())
-
-        # Changing field 'NamedAttribute.name'
-        db.alter_column('dashboard_app_namedattribute', 'name', self.gf('django.db.models.fields.TextField')())
-
-
-    def backwards(self, orm):
-        
-        # Changing field 'NamedAttribute.value'
-        db.alter_column('dashboard_app_namedattribute', 'value', self.gf('django.db.models.fields.CharField')(max_length=512))
-
-        # Changing field 'NamedAttribute.name'
-        db.alter_column('dashboard_app_namedattribute', 'name', self.gf('django.db.models.fields.CharField')(max_length=32))
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0012_auto__del_field_bundle_content__add_field_bundle__raw_content__add_fie.py'
--- dashboard_app/migrations/0012_auto__del_field_bundle_content__add_field_bundle__raw_content__add_fie.py	2012-01-19 14:39:18 +0000
+++ dashboard_app/migrations/0012_auto__del_field_bundle_content__add_field_bundle__raw_content__add_fie.py	1970-01-01 00:00:00 +0000
@@ -1,212 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Adding field 'Bundle._gz_content'
-        db.add_column('dashboard_app_bundle', '_gz_content', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, db_column='gz_content'), keep_default=False)
-
-
-    def backwards(self, orm):
-
-        # Deleting field 'Bundle._gz_content'
-        db.delete_column('dashboard_app_bundle', 'gz_content')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'units': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0013_auto__chg_field_testcase_units__chg_field_testcase_test_case_id__chg_f.py'
--- dashboard_app/migrations/0013_auto__chg_field_testcase_units__chg_field_testcase_test_case_id__chg_f.py	2012-01-30 09:53:38 +0000
+++ dashboard_app/migrations/0013_auto__chg_field_testcase_units__chg_field_testcase_test_case_id__chg_f.py	1970-01-01 00:00:00 +0000
@@ -1,224 +0,0 @@
-# encoding: utf-8
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        
-        # Changing field 'TestCase.units'
-        db.alter_column('dashboard_app_testcase', 'units', self.gf('django.db.models.fields.TextField')())
-
-        # Changing field 'TestCase.test_case_id'
-        db.alter_column('dashboard_app_testcase', 'test_case_id', self.gf('django.db.models.fields.TextField')())
-
-        # Changing field 'TestCase.name'
-        db.alter_column('dashboard_app_testcase', 'name', self.gf('django.db.models.fields.TextField')())
-
-
-    def backwards(self, orm):
-        
-        # Changing field 'TestCase.units'
-        db.alter_column('dashboard_app_testcase', 'units', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'TestCase.test_case_id'
-        db.alter_column('dashboard_app_testcase', 'test_case_id', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-        # Changing field 'TestCase.name'
-        db.alter_column('dashboard_app_testcase', 'name', self.gf('django.db.models.fields.CharField')(max_length=100))
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256', 'db_index': 'True'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100', 'db_index': 'True'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0014_auto__add_imageset__add_image__add_imageattribute.py'
--- dashboard_app/migrations/0014_auto__add_imageset__add_image__add_imageattribute.py	2012-07-12 04:58:23 +0000
+++ dashboard_app/migrations/0014_auto__add_imageset__add_image__add_imageattribute.py	1970-01-01 00:00:00 +0000
@@ -1,280 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'ImageSet'
-        db.create_table('dashboard_app_imageset', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=1024)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageSet'])
-
-        # Adding M2M table for field images on 'ImageSet'
-        db.create_table('dashboard_app_imageset_images', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('imageset', models.ForeignKey(orm['dashboard_app.imageset'], null=False)),
-            ('image', models.ForeignKey(orm['dashboard_app.image'], null=False))
-        ))
-        db.create_unique('dashboard_app_imageset_images', ['imageset_id', 'image_id'])
-
-        # Adding model 'Image'
-        db.create_table('dashboard_app_image', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=1024)),
-            ('build_number_attribute', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-        ))
-        db.send_create_signal('dashboard_app', ['Image'])
-
-        # Adding M2M table for field bundle_streams on 'Image'
-        db.create_table('dashboard_app_image_bundle_streams', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('image', models.ForeignKey(orm['dashboard_app.image'], null=False)),
-            ('bundlestream', models.ForeignKey(orm['dashboard_app.bundlestream'], null=False))
-        ))
-        db.create_unique('dashboard_app_image_bundle_streams', ['image_id', 'bundlestream_id'])
-
-        # Adding model 'ImageAttribute'
-        db.create_table('dashboard_app_imageattribute', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('value', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('image', self.gf('django.db.models.fields.related.ForeignKey')(related_name='required_attributes', to=orm['dashboard_app.Image'])),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageAttribute'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'ImageSet'
-        db.delete_table('dashboard_app_imageset')
-
-        # Removing M2M table for field images on 'ImageSet'
-        db.delete_table('dashboard_app_imageset_images')
-
-        # Deleting model 'Image'
-        db.delete_table('dashboard_app_image')
-
-        # Removing M2M table for field bundle_streams on 'Image'
-        db.delete_table('dashboard_app_image_bundle_streams')
-
-        # Deleting model 'ImageAttribute'
-        db.delete_table('dashboard_app_imageattribute')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0015_auto__add_launchpadbug.py'
--- dashboard_app/migrations/0015_auto__add_launchpadbug.py	2012-07-13 03:46:23 +0000
+++ dashboard_app/migrations/0015_auto__add_launchpadbug.py	1970-01-01 00:00:00 +0000
@@ -1,252 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'LaunchpadBug'
-        db.create_table('dashboard_app_launchpadbug', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('bug_id', self.gf('django.db.models.fields.PositiveIntegerField')(unique=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['LaunchpadBug'])
-
-        # Adding M2M table for field test_runs on 'LaunchpadBug'
-        db.create_table('dashboard_app_launchpadbug_test_runs', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('launchpadbug', models.ForeignKey(orm['dashboard_app.launchpadbug'], null=False)),
-            ('testrun', models.ForeignKey(orm['dashboard_app.testrun'], null=False))
-        ))
-        db.create_unique('dashboard_app_launchpadbug_test_runs', ['launchpadbug_id', 'testrun_id'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'LaunchpadBug'
-        db.delete_table('dashboard_app_launchpadbug')
-
-        # Removing M2M table for field test_runs on 'LaunchpadBug'
-        db.delete_table('dashboard_app_launchpadbug_test_runs')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.TestRun']", 'symmetrical': 'False'})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0016_auto__add_field_image_uploaded_by__chg_field_image_name.py'
--- dashboard_app/migrations/0016_auto__add_field_image_uploaded_by__chg_field_image_name.py	2012-07-18 05:32:28 +0000
+++ dashboard_app/migrations/0016_auto__add_field_image_uploaded_by__chg_field_image_name.py	1970-01-01 00:00:00 +0000
@@ -1,252 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'Image.uploaded_by'
-        db.add_column('dashboard_app_image', 'uploaded_by',
-                      self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True),
-                      keep_default=False)
-
-
-        # Changing field 'Image.name'
-        db.alter_column('dashboard_app_image', 'name', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=1024))
-        # Adding index on 'Image', fields ['name']
-        db.create_index('dashboard_app_image', ['name'])
-
-
-    def backwards(self, orm):
-        # Removing index on 'Image', fields ['name']
-        db.delete_index('dashboard_app_image', ['name'])
-
-        # Deleting field 'Image.uploaded_by'
-        db.delete_column('dashboard_app_image', 'uploaded_by_id')
-
-
-        # Changing field 'Image.name'
-        db.alter_column('dashboard_app_image', 'name', self.gf('django.db.models.fields.CharField')(max_length=1024, unique=True))
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0017_auto__add_testrunfilterattribute__add_testrunfilter__add_unique_testru.py'
--- dashboard_app/migrations/0017_auto__add_testrunfilterattribute__add_testrunfilter__add_unique_testru.py	2012-08-13 01:30:49 +0000
+++ dashboard_app/migrations/0017_auto__add_testrunfilterattribute__add_testrunfilter__add_unique_testru.py	1970-01-01 00:00:00 +0000
@@ -1,290 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'TestRunFilterAttribute'
-        db.create_table('dashboard_app_testrunfilterattribute', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('value', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('filter', self.gf('django.db.models.fields.related.ForeignKey')(related_name='attributes', to=orm['dashboard_app.TestRunFilter'])),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRunFilterAttribute'])
-
-        # Adding model 'TestRunFilter'
-        db.create_table('dashboard_app_testrunfilter', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('owner', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
-            ('name', self.gf('django.db.models.fields.SlugField')(max_length=1024)),
-            ('test', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.Test'], null=True, blank=True)),
-            ('test_case', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestCase'], null=True, blank=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRunFilter'])
-
-        # Adding M2M table for field bundle_streams on 'TestRunFilter'
-        db.create_table('dashboard_app_testrunfilter_bundle_streams', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testrunfilter', models.ForeignKey(orm['dashboard_app.testrunfilter'], null=False)),
-            ('bundlestream', models.ForeignKey(orm['dashboard_app.bundlestream'], null=False))
-        ))
-        db.create_unique('dashboard_app_testrunfilter_bundle_streams', ['testrunfilter_id', 'bundlestream_id'])
-
-        # Adding unique constraint on 'TestRunFilter', fields ['owner', 'name']
-        db.create_unique('dashboard_app_testrunfilter', ['owner_id', 'name'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'TestRunFilter', fields ['owner', 'name']
-        db.delete_unique('dashboard_app_testrunfilter', ['owner_id', 'name'])
-
-        # Deleting model 'TestRunFilterAttribute'
-        db.delete_table('dashboard_app_testrunfilterattribute')
-
-        # Deleting model 'TestRunFilter'
-        db.delete_table('dashboard_app_testrunfilter')
-
-        # Removing M2M table for field bundle_streams on 'TestRunFilter'
-        db.delete_table('dashboard_app_testrunfilter_bundle_streams')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Test']", 'null': 'True', 'blank': 'True'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0018_auto__add_field_testrunfilter_public.py'
--- dashboard_app/migrations/0018_auto__add_field_testrunfilter_public.py	2012-08-15 23:40:53 +0000
+++ dashboard_app/migrations/0018_auto__add_field_testrunfilter_public.py	1970-01-01 00:00:00 +0000
@@ -1,257 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'TestRunFilter.public'
-        db.add_column('dashboard_app_testrunfilter', 'public',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'TestRunFilter.public'
-        db.delete_column('dashboard_app_testrunfilter', 'public')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Test']", 'null': 'True', 'blank': 'True'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0019_auto__add_testrunfiltersubscription__add_unique_testrunfiltersubscript.py'
--- dashboard_app/migrations/0019_auto__add_testrunfiltersubscription__add_unique_testrunfiltersubscript.py	2012-08-16 00:44:01 +0000
+++ dashboard_app/migrations/0019_auto__add_testrunfiltersubscription__add_unique_testrunfiltersubscript.py	1970-01-01 00:00:00 +0000
@@ -1,274 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'TestRunFilterSubscription'
-        db.create_table('dashboard_app_testrunfiltersubscription', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
-            ('filter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestRunFilter'])),
-            ('level', self.gf('django.db.models.fields.IntegerField')(default=0)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRunFilterSubscription'])
-
-        # Adding unique constraint on 'TestRunFilterSubscription', fields ['user', 'filter']
-        db.create_unique('dashboard_app_testrunfiltersubscription', ['user_id', 'filter_id'])
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'TestRunFilterSubscription', fields ['user', 'filter']
-        db.delete_unique('dashboard_app_testrunfiltersubscription', ['user_id', 'filter_id'])
-
-        # Deleting model 'TestRunFilterSubscription'
-        db.delete_table('dashboard_app_testrunfiltersubscription')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Test']", 'null': 'True', 'blank': 'True'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0020_auto__add_field_testrunfilter_build_number_attribute.py'
--- dashboard_app/migrations/0020_auto__add_field_testrunfilter_build_number_attribute.py	2012-09-04 00:37:05 +0000
+++ dashboard_app/migrations/0020_auto__add_field_testrunfilter_build_number_attribute.py	1970-01-01 00:00:00 +0000
@@ -1,265 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'TestRunFilter.build_number_attribute'
-        db.add_column('dashboard_app_testrunfilter', 'build_number_attribute',
-                      self.gf('django.db.models.fields.CharField')(max_length=1024, null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'TestRunFilter.build_number_attribute'
-        db.delete_column('dashboard_app_testrunfilter', 'build_number_attribute')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Test']", 'null': 'True', 'blank': 'True'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0021_add_cast_integer.py'
--- dashboard_app/migrations/0021_add_cast_integer.py	2012-09-06 03:12:26 +0000
+++ dashboard_app/migrations/0021_add_cast_integer.py	1970-01-01 00:00:00 +0000
@@ -1,280 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-import django.db.utils
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        db.start_transaction()
-        try:
-            db.execute("CREATE LANGUAGE plpgsql")
-        except django.db.utils.DatabaseError:
-            db.rollback_transaction()
-            db.start_transaction()
-        db.execute("""
-CREATE FUNCTION convert_to_integer(v_input text)
-RETURNS INTEGER AS $a$
-DECLARE v_int_value INTEGER DEFAULT NULL;
-BEGIN
-    BEGIN
-        v_int_value := v_input::INTEGER;
-    EXCEPTION WHEN OTHERS THEN
-        RETURN NULL;
-    END;
-RETURN v_int_value;
-END;
-$a$ LANGUAGE plpgsql;
-        """)
-        db.commit_transaction()
-
-    def backwards(self, orm):
-        db.execute("""DROP FUNCTION convert_to_integer (v_input text)""")
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Test']", 'null': 'True', 'blank': 'True'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']

=== removed file 'dashboard_app/migrations/0022_auto__add_testrunfiltertest__add_testrunfiltertestcase__del_field_test.py'
--- dashboard_app/migrations/0022_auto__add_testrunfiltertest__add_testrunfiltertestcase__del_field_test.py	2012-09-12 01:16:05 +0000
+++ dashboard_app/migrations/0022_auto__add_testrunfiltertest__add_testrunfiltertestcase__del_field_test.py	1970-01-01 00:00:00 +0000
@@ -1,309 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'TestRunFilterTest'
-        db.create_table('dashboard_app_testrunfiltertest', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('test', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['dashboard_app.Test'])),
-            ('filter', self.gf('django.db.models.fields.related.ForeignKey')(related_name='tests', to=orm['dashboard_app.TestRunFilter'])),
-            ('index', self.gf('django.db.models.fields.PositiveIntegerField')()),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRunFilterTest'])
-
-        # Adding model 'TestRunFilterTestCase'
-        db.create_table('dashboard_app_testrunfiltertestcase', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('test_case', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['dashboard_app.TestCase'])),
-            ('test', self.gf('django.db.models.fields.related.ForeignKey')(related_name='cases', to=orm['dashboard_app.TestRunFilterTest'])),
-            ('index', self.gf('django.db.models.fields.PositiveIntegerField')()),
-        ))
-        db.send_create_signal('dashboard_app', ['TestRunFilterTestCase'])
-
-        # Deleting field 'TestRunFilter.test'
-        db.delete_column('dashboard_app_testrunfilter', 'test_id')
-
-        # Deleting field 'TestRunFilter.test_case'
-        db.delete_column('dashboard_app_testrunfilter', 'test_case_id')
-
-
-    def backwards(self, orm):
-        # Deleting model 'TestRunFilterTest'
-        db.delete_table('dashboard_app_testrunfiltertest')
-
-        # Deleting model 'TestRunFilterTestCase'
-        db.delete_table('dashboard_app_testrunfiltertestcase')
-
-        # Adding field 'TestRunFilter.test'
-        db.add_column('dashboard_app_testrunfilter', 'test',
-                      self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.Test'], null=True, blank=True),
-                      keep_default=False)
-
-        # Adding field 'TestRunFilter.test_case'
-        db.add_column('dashboard_app_testrunfilter', 'test_case',
-                      self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestCase'], null=True, blank=True),
-                      keep_default=False)
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0023_auto__add_field_testrunfilter_uploaded_by__add_field_testrunfilter_ena.py'
--- dashboard_app/migrations/0023_auto__add_field_testrunfilter_uploaded_by__add_field_testrunfilter_ena.py	2012-09-24 03:50:34 +0000
+++ dashboard_app/migrations/0023_auto__add_field_testrunfilter_uploaded_by__add_field_testrunfilter_ena.py	1970-01-01 00:00:00 +0000
@@ -1,299 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding M2M table for field filters on 'ImageSet'
-        db.create_table('dashboard_app_imageset_filters', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('imageset', models.ForeignKey(orm['dashboard_app.imageset'], null=False)),
-            ('testrunfilter', models.ForeignKey(orm['dashboard_app.testrunfilter'], null=False))
-        ))
-        db.create_unique('dashboard_app_imageset_filters', ['imageset_id', 'testrunfilter_id'])
-
-        # Adding field 'TestRunFilter.uploaded_by'
-        db.add_column('dashboard_app_testrunfilter', 'uploaded_by',
-                      self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='+', null=True, to=orm['auth.User']),
-                      keep_default=False)
-
-        # Adding field 'TestRunFilter.enable_as_image'
-        db.add_column('dashboard_app_testrunfilter', 'enable_as_image',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Removing M2M table for field filters on 'ImageSet'
-        db.delete_table('dashboard_app_imageset_filters')
-
-        # Deleting field 'TestRunFilter.uploaded_by'
-        db.delete_column('dashboard_app_testrunfilter', 'uploaded_by_id')
-
-        # Deleting field 'TestRunFilter.enable_as_image'
-        db.delete_column('dashboard_app_testrunfilter', 'enable_as_image')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.imageattribute': {
-            'Meta': {'object_name': 'ImageAttribute'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'required_attributes'", 'to': "orm['dashboard_app.Image']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'filters': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.TestRunFilter']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'enable_as_image': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0024_auto__del_imageattribute__del_field_image_uploaded_by__del_field_image.py'
--- dashboard_app/migrations/0024_auto__del_imageattribute__del_field_image_uploaded_by__del_field_image.py	2012-09-25 22:21:40 +0000
+++ dashboard_app/migrations/0024_auto__del_imageattribute__del_field_image_uploaded_by__del_field_image.py	1970-01-01 00:00:00 +0000
@@ -1,325 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting model 'ImageAttribute'
-        db.delete_table('dashboard_app_imageattribute')
-
-        # Deleting field 'Image.uploaded_by'
-        db.delete_column('dashboard_app_image', 'uploaded_by_id')
-
-        # Deleting field 'Image.build_number_attribute'
-        db.delete_column('dashboard_app_image', 'build_number_attribute')
-
-        # Adding field 'Image.filter'
-        db.add_column('dashboard_app_image', 'filter',
-                      self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', null=True, to=orm['dashboard_app.TestRunFilter']),
-                      keep_default=False)
-
-        # Removing M2M table for field bundle_streams on 'Image'
-        db.delete_table('dashboard_app_image_bundle_streams')
-
-        # Removing M2M table for field filters on 'ImageSet'
-        db.delete_table('dashboard_app_imageset_filters')
-
-        # Deleting field 'TestRunFilter.enable_as_image'
-        db.delete_column('dashboard_app_testrunfilter', 'enable_as_image')
-
-
-    def backwards(self, orm):
-        # Adding model 'ImageAttribute'
-        db.create_table('dashboard_app_imageattribute', (
-            ('image', self.gf('django.db.models.fields.related.ForeignKey')(related_name='required_attributes', to=orm['dashboard_app.Image'])),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('value', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageAttribute'])
-
-        # Adding field 'Image.uploaded_by'
-        db.add_column('dashboard_app_image', 'uploaded_by',
-                      self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, blank=True),
-                      keep_default=False)
-
-
-        # User chose to not deal with backwards NULL issues for 'Image.build_number_attribute'
-        raise RuntimeError("Cannot reverse this migration. 'Image.build_number_attribute' and its values cannot be restored.")
-        # Deleting field 'Image.filter'
-        db.delete_column('dashboard_app_image', 'filter_id')
-
-        # Adding M2M table for field bundle_streams on 'Image'
-        db.create_table('dashboard_app_image_bundle_streams', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('image', models.ForeignKey(orm['dashboard_app.image'], null=False)),
-            ('bundlestream', models.ForeignKey(orm['dashboard_app.bundlestream'], null=False))
-        ))
-        db.create_unique('dashboard_app_image_bundle_streams', ['image_id', 'bundlestream_id'])
-
-        # Adding M2M table for field filters on 'ImageSet'
-        db.create_table('dashboard_app_imageset_filters', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('imageset', models.ForeignKey(orm['dashboard_app.imageset'], null=False)),
-            ('testrunfilter', models.ForeignKey(orm['dashboard_app.testrunfilter'], null=False))
-        ))
-        db.create_unique('dashboard_app_imageset_filters', ['imageset_id', 'testrunfilter_id'])
-
-        # Adding field 'TestRunFilter.enable_as_image'
-        db.add_column('dashboard_app_testrunfilter', 'enable_as_image',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0025_auto__add_field_testrun_microseconds.py'
--- dashboard_app/migrations/0025_auto__add_field_testrun_microseconds.py	2012-11-07 02:47:08 +0000
+++ dashboard_app/migrations/0025_auto__add_field_testrun_microseconds.py	1970-01-01 00:00:00 +0000
@@ -1,270 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding field 'TestRun.microseconds'
-        db.add_column('dashboard_app_testrun', 'microseconds',
-                      self.gf('django.db.models.fields.BigIntegerField')(null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Deleting field 'TestRun.microseconds'
-        db.delete_column('dashboard_app_testrun', 'microseconds')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0026_auto__add_pmqabundlestream.py'
--- dashboard_app/migrations/0026_auto__add_pmqabundlestream.py	2013-01-09 02:52:50 +0000
+++ dashboard_app/migrations/0026_auto__add_pmqabundlestream.py	1970-01-01 00:00:00 +0000
@@ -1,277 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'PMQABundleStream'
-        db.create_table('dashboard_app_pmqabundlestream', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('bundle_stream', self.gf('django.db.models.fields.related.ForeignKey')(related_name='+', to=orm['dashboard_app.BundleStream'])),
-        ))
-        db.send_create_signal('dashboard_app', ['PMQABundleStream'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'PMQABundleStream'
-        db.delete_table('dashboard_app_pmqabundlestream')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.pmqabundlestream': {
-            'Meta': {'object_name': 'PMQABundleStream'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testingeffort': {
-            'Meta': {'object_name': 'TestingEffort'},
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'testing_efforts'", 'to': "orm['lava_projects.Project']"}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'testing_efforts'", 'symmetrical': 'False', 'to': "orm['dashboard_app.Tag']"})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        },
-        'lava_projects.project': {
-            'Meta': {'object_name': 'Project'},
-            'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'identifier': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '100'}),
-            'is_aggregate': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'registered_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'projects'", 'to': "orm['auth.User']"}),
-            'registered_on': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0027_auto__del_testingeffort.py'
--- dashboard_app/migrations/0027_auto__del_testingeffort.py	2013-01-11 16:25:54 +0000
+++ dashboard_app/migrations/0027_auto__del_testingeffort.py	1970-01-01 00:00:00 +0000
@@ -1,269 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting model 'TestingEffort'
-        db.delete_table('dashboard_app_testingeffort')
-
-        # Removing M2M table for field tags on 'TestingEffort'
-        db.delete_table('dashboard_app_testingeffort_tags')
-
-
-    def backwards(self, orm):
-        # Adding model 'TestingEffort'
-        db.create_table('dashboard_app_testingeffort', (
-            ('description', self.gf('django.db.models.fields.TextField')()),
-            ('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='testing_efforts', to=orm['lava_projects.Project'])),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestingEffort'])
-
-        # Adding M2M table for field tags on 'TestingEffort'
-        db.create_table('dashboard_app_testingeffort_tags', (
-            ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
-            ('testingeffort', models.ForeignKey(orm['dashboard_app.testingeffort'], null=False)),
-            ('tag', models.ForeignKey(orm['dashboard_app.tag'], null=False))
-        ))
-        db.create_unique('dashboard_app_testingeffort_tags', ['testingeffort_id', 'tag_id'])
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.pmqabundlestream': {
-            'Meta': {'object_name': 'PMQABundleStream'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '64'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0028_auto__chg_field_test_test_id__chg_field_test_name.py'
--- dashboard_app/migrations/0028_auto__chg_field_test_test_id__chg_field_test_name.py	2013-02-07 22:31:00 +0000
+++ dashboard_app/migrations/0028_auto__chg_field_test_test_id__chg_field_test_name.py	1970-01-01 00:00:00 +0000
@@ -1,258 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-
-        # Changing field 'Test.test_id'
-        db.alter_column('dashboard_app_test', 'test_id', self.gf('django.db.models.fields.CharField')(unique=True, max_length=1024))
-
-        # Changing field 'Test.name'
-        db.alter_column('dashboard_app_test', 'name', self.gf('django.db.models.fields.CharField')(max_length=1024))
-
-    def backwards(self, orm):
-
-        # Changing field 'Test.test_id'
-        db.alter_column('dashboard_app_test', 'test_id', self.gf('django.db.models.fields.CharField')(max_length=64, unique=True))
-
-        # Changing field 'Test.name'
-        db.alter_column('dashboard_app_test', 'name', self.gf('django.db.models.fields.CharField')(max_length=64))
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.pmqabundlestream': {
-            'Meta': {'object_name': 'PMQABundleStream'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0029_auto__add_testdefinition.py'
--- dashboard_app/migrations/0029_auto__add_testdefinition.py	2013-04-01 10:16:02 +0000
+++ dashboard_app/migrations/0029_auto__add_testdefinition.py	1970-01-01 00:00:00 +0000
@@ -1,281 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'TestDefinition'
-        db.create_table('dashboard_app_testdefinition', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=512)),
-            ('version', self.gf('django.db.models.fields.CharField')(max_length=256)),
-            ('description', self.gf('django.db.models.fields.TextField')()),
-            ('format', self.gf('django.db.models.fields.CharField')(max_length=128)),
-            ('location', self.gf('django.db.models.fields.CharField')(default='LOCAL', max_length=64)),
-            ('url', self.gf('django.db.models.fields.CharField')(max_length=1024)),
-            ('environment', self.gf('django.db.models.fields.CharField')(max_length=256)),
-            ('target_os', self.gf('django.db.models.fields.CharField')(max_length=512)),
-            ('target_dev_types', self.gf('django.db.models.fields.CharField')(max_length=512)),
-            ('content', self.gf('django.db.models.fields.files.FileField')(max_length=100, null=True, blank=True)),
-            ('mime_type', self.gf('django.db.models.fields.CharField')(default='text/plain', max_length=64)),
-        ))
-        db.send_create_signal('dashboard_app', ['TestDefinition'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'TestDefinition'
-        db.delete_table('dashboard_app_testdefinition')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.pmqabundlestream': {
-            'Meta': {'object_name': 'PMQABundleStream'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testdefinition': {
-            'Meta': {'object_name': 'TestDefinition'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'environment': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'format': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'location': ('django.db.models.fields.CharField', [], {'default': "'LOCAL'", 'max_length': '64'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'default': "'text/plain'", 'max_length': '64'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
-            'target_dev_types': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'target_os': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '256'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py'
--- dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py	2013-09-13 14:16:05 +0000
+++ dashboard_app/migrations/0030_auto__add_imagecharttestcase__add_imagereport__add_imagecharttestrun__.py	1970-01-01 00:00:00 +0000
@@ -1,345 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Adding model 'ImageChartTestCase'
-        db.create_table('dashboard_app_imagecharttestcase', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('image_chart', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageReportChart'])),
-            ('test_case', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestCase'])),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageChartTestCase'])
-
-        # Adding model 'ImageReport'
-        db.create_table('dashboard_app_imagereport', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.SlugField')(unique=True, max_length=1024)),
-            ('description', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageReport'])
-
-        # Adding model 'ImageChartTestRun'
-        db.create_table('dashboard_app_imagecharttestrun', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('image_chart', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageReportChart'])),
-            ('test_run', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestRun'])),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageChartTestRun'])
-
-        # Adding model 'ImageReportChart'
-        db.create_table('dashboard_app_imagereportchart', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=100)),
-            ('image_report', self.gf('django.db.models.fields.related.ForeignKey')(default=None, to=orm['dashboard_app.ImageReport'])),
-            ('chart_type', self.gf('django.db.models.fields.CharField')(max_length=20)),
-            ('representation', self.gf('django.db.models.fields.CharField')(max_length=20)),
-            ('target_goal', self.gf('django.db.models.fields.DecimalField')(null=True, max_digits=10, decimal_places=5, blank=True)),
-            ('is_interactive', self.gf('django.db.models.fields.BooleanField')(default=False)),
-            ('is_data_table_visible', self.gf('django.db.models.fields.BooleanField')(default=False)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageReportChart'])
-
-
-    def backwards(self, orm):
-        # Deleting model 'ImageChartTestCase'
-        db.delete_table('dashboard_app_imagecharttestcase')
-
-        # Deleting model 'ImageReport'
-        db.delete_table('dashboard_app_imagereport')
-
-        # Deleting model 'ImageChartTestRun'
-        db.delete_table('dashboard_app_imagecharttestrun')
-
-        # Deleting model 'ImageReportChart'
-        db.delete_table('dashboard_app_imagereportchart')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imagecharttestcase': {
-            'Meta': {'object_name': 'ImageChartTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_chart': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageReportChart']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']"})
-        },
-        'dashboard_app.imagecharttestrun': {
-            'Meta': {'object_name': 'ImageChartTestRun'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_chart': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageReportChart']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.imagereport': {
-            'Meta': {'object_name': 'ImageReport'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imagereportchart': {
-            'Meta': {'object_name': 'ImageReportChart'},
-            'chart_type': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_report': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dashboard_app.ImageReport']"}),
-            'is_data_table_visible': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_interactive': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'representation': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
-            'target_goal': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '5', 'blank': 'True'}),
-            'test_cases': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.TestCase']", 'through': "orm['dashboard_app.ImageChartTestCase']", 'symmetrical': 'False'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.TestRun']", 'through': "orm['dashboard_app.ImageChartTestRun']", 'symmetrical': 'False'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.pmqabundlestream': {
-            'Meta': {'object_name': 'PMQABundleStream'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testdefinition': {
-            'Meta': {'object_name': 'TestDefinition'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'environment': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'format': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'location': ('django.db.models.fields.CharField', [], {'default': "'LOCAL'", 'max_length': '64'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'default': "'text/plain'", 'max_length': '64'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
-            'target_dev_types': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'target_os': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '256'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/0031_auto__del_imagecharttestrun__add_imagecharttest__add_unique_imagechart.py'
--- dashboard_app/migrations/0031_auto__del_imagecharttestrun__add_imagecharttest__add_unique_imagechart.py	2013-09-13 11:45:52 +0000
+++ dashboard_app/migrations/0031_auto__del_imagecharttestrun__add_imagecharttest__add_unique_imagechart.py	1970-01-01 00:00:00 +0000
@@ -1,388 +0,0 @@
-# -*- coding: utf-8 -*-
-import datetime
-from south.db import db
-from south.v2 import SchemaMigration
-from django.db import models
-
-
-class Migration(SchemaMigration):
-
-    def forwards(self, orm):
-        # Deleting model 'ImageChartTestRun'
-        db.delete_table('dashboard_app_imagecharttestrun')
-
-        # Adding model 'ImageChartTest'
-        db.create_table('dashboard_app_imagecharttest', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('image_chart_filter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageChartFilter'])),
-            ('test', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.Test'])),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageChartTest'])
-
-        # Adding unique constraint on 'ImageChartTest', fields ['image_chart_filter', 'test']
-        db.create_unique('dashboard_app_imagecharttest', ['image_chart_filter_id', 'test_id'])
-
-        # Adding model 'ImageChartFilter'
-        db.create_table('dashboard_app_imagechartfilter', (
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('image_chart', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageReportChart'])),
-            ('filter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestRunFilter'], null=True, on_delete=models.SET_NULL)),
-            ('representation', self.gf('django.db.models.fields.CharField')(default='lines', max_length=20)),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageChartFilter'])
-
-        # Deleting field 'ImageChartTestCase.image_chart'
-        db.delete_column('dashboard_app_imagecharttestcase', 'image_chart_id')
-
-        # Adding field 'ImageChartTestCase.image_chart_filter'
-        db.add_column('dashboard_app_imagecharttestcase', 'image_chart_filter',
-                      self.gf('django.db.models.fields.related.ForeignKey')(default=0, to=orm['dashboard_app.ImageChartFilter']),
-                      keep_default=False)
-
-        # Adding unique constraint on 'ImageChartTestCase', fields ['image_chart_filter', 'test_case']
-        db.create_unique('dashboard_app_imagecharttestcase', ['image_chart_filter_id', 'test_case_id'])
-
-        # Adding field 'ImageReport.is_published'
-        db.add_column('dashboard_app_imagereport', 'is_published',
-                      self.gf('django.db.models.fields.BooleanField')(default=False),
-                      keep_default=False)
-
-        # Deleting field 'ImageReportChart.representation'
-        db.delete_column('dashboard_app_imagereportchart', 'representation')
-
-        # Adding field 'ImageReportChart.description'
-        db.add_column('dashboard_app_imagereportchart', 'description',
-                      self.gf('django.db.models.fields.TextField')(null=True, blank=True),
-                      keep_default=False)
-
-
-    def backwards(self, orm):
-        # Removing unique constraint on 'ImageChartTestCase', fields ['image_chart_filter', 'test_case']
-        db.delete_unique('dashboard_app_imagecharttestcase', ['image_chart_filter_id', 'test_case_id'])
-
-        # Removing unique constraint on 'ImageChartTest', fields ['image_chart_filter', 'test']
-        db.delete_unique('dashboard_app_imagecharttest', ['image_chart_filter_id', 'test_id'])
-
-        # Adding model 'ImageChartTestRun'
-        db.create_table('dashboard_app_imagecharttestrun', (
-            ('test_run', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.TestRun'])),
-            ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
-            ('name', self.gf('django.db.models.fields.CharField')(max_length=200)),
-            ('image_chart', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['dashboard_app.ImageReportChart'])),
-        ))
-        db.send_create_signal('dashboard_app', ['ImageChartTestRun'])
-
-        # Deleting model 'ImageChartTest'
-        db.delete_table('dashboard_app_imagecharttest')
-
-        # Deleting model 'ImageChartFilter'
-        db.delete_table('dashboard_app_imagechartfilter')
-
-        # Adding field 'ImageChartTestCase.image_chart'
-        db.add_column('dashboard_app_imagecharttestcase', 'image_chart',
-                      self.gf('django.db.models.fields.related.ForeignKey')(default=0, to=orm['dashboard_app.ImageReportChart']),
-                      keep_default=False)
-
-        # Deleting field 'ImageChartTestCase.image_chart_filter'
-        db.delete_column('dashboard_app_imagecharttestcase', 'image_chart_filter_id')
-
-        # Deleting field 'ImageReport.is_published'
-        db.delete_column('dashboard_app_imagereport', 'is_published')
-
-        # Adding field 'ImageReportChart.representation'
-        db.add_column('dashboard_app_imagereportchart', 'representation',
-                      self.gf('django.db.models.fields.CharField')(default='pass/fail', max_length=20),
-                      keep_default=False)
-
-        # Deleting field 'ImageReportChart.description'
-        db.delete_column('dashboard_app_imagereportchart', 'description')
-
-
-    models = {
-        'auth.group': {
-            'Meta': {'object_name': 'Group'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
-            'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
-        },
-        'auth.permission': {
-            'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
-            'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
-        },
-        'auth.user': {
-            'Meta': {'object_name': 'User'},
-            'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
-            'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
-            'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
-            'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
-            'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
-            'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
-        },
-        'contenttypes.contenttype': {
-            'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
-            'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
-        },
-        'dashboard_app.attachment': {
-            'Meta': {'object_name': 'Attachment'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True'}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '64'}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'public_url': ('django.db.models.fields.URLField', [], {'max_length': '512', 'blank': 'True'})
-        },
-        'dashboard_app.bundle': {
-            'Meta': {'ordering': "['-uploaded_on']", 'object_name': 'Bundle'},
-            '_gz_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'gz_content'"}),
-            '_raw_content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'db_column': "'content'"}),
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'bundles'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'content_filename': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'content_sha1': ('django.db.models.fields.CharField', [], {'max_length': '40', 'unique': 'True', 'null': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_deserialized': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'uploaded_bundles'", 'null': 'True', 'to': "orm['auth.User']"}),
-            'uploaded_on': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.utcnow'})
-        },
-        'dashboard_app.bundledeserializationerror': {
-            'Meta': {'object_name': 'BundleDeserializationError'},
-            'bundle': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'deserialization_error'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.Bundle']"}),
-            'error_message': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'traceback': ('django.db.models.fields.TextField', [], {'max_length': '32768'})
-        },
-        'dashboard_app.bundlestream': {
-            'Meta': {'object_name': 'BundleStream'},
-            'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']", 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'pathname': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}),
-            'slug': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.hardwaredevice': {
-            'Meta': {'object_name': 'HardwareDevice'},
-            'description': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'device_type': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.image': {
-            'Meta': {'object_name': 'Image'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'null': 'True', 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imagechartfilter': {
-            'Meta': {'object_name': 'ImageChartFilter'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']", 'null': 'True', 'on_delete': 'models.SET_NULL'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_chart': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageReportChart']"}),
-            'representation': ('django.db.models.fields.CharField', [], {'default': "'lines'", 'max_length': '20'})
-        },
-        'dashboard_app.imagecharttest': {
-            'Meta': {'unique_together': "(('image_chart_filter', 'test'),)", 'object_name': 'ImageChartTest'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_chart_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageChartFilter']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.imagecharttestcase': {
-            'Meta': {'unique_together': "(('image_chart_filter', 'test_case'),)", 'object_name': 'ImageChartTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_chart_filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.ImageChartFilter']"}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestCase']"})
-        },
-        'dashboard_app.imagereport': {
-            'Meta': {'object_name': 'ImageReport'},
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'is_published': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.imagereportchart': {
-            'Meta': {'object_name': 'ImageReportChart'},
-            'chart_type': ('django.db.models.fields.CharField', [], {'default': "'pass/fail'", 'max_length': '20'}),
-            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'image_report': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': "orm['dashboard_app.ImageReport']"}),
-            'is_data_table_visible': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'is_interactive': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
-            'target_goal': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '10', 'decimal_places': '5', 'blank': 'True'})
-        },
-        'dashboard_app.imageset': {
-            'Meta': {'object_name': 'ImageSet'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'images': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.Image']", 'symmetrical': 'False'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.launchpadbug': {
-            'Meta': {'object_name': 'LaunchpadBug'},
-            'bug_id': ('django.db.models.fields.PositiveIntegerField', [], {'unique': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'test_runs': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'launchpad_bugs'", 'symmetrical': 'False', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.namedattribute': {
-            'Meta': {'unique_together': "(('object_id', 'name'),)", 'object_name': 'NamedAttribute'},
-            'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {}),
-            'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'value': ('django.db.models.fields.TextField', [], {})
-        },
-        'dashboard_app.pmqabundlestream': {
-            'Meta': {'object_name': 'PMQABundleStream'},
-            'bundle_stream': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.BundleStream']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
-        },
-        'dashboard_app.softwarepackage': {
-            'Meta': {'unique_together': "(('name', 'version'),)", 'object_name': 'SoftwarePackage'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwarepackagescratch': {
-            'Meta': {'object_name': 'SoftwarePackageScratch'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '128'})
-        },
-        'dashboard_app.softwaresource': {
-            'Meta': {'object_name': 'SoftwareSource'},
-            'branch_revision': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'branch_url': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'branch_vcs': ('django.db.models.fields.CharField', [], {'max_length': '10'}),
-            'commit_timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'project_name': ('django.db.models.fields.CharField', [], {'max_length': '32'})
-        },
-        'dashboard_app.tag': {
-            'Meta': {'object_name': 'Tag'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '256'})
-        },
-        'dashboard_app.test': {
-            'Meta': {'object_name': 'Test'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'blank': 'True'}),
-            'test_id': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '1024'})
-        },
-        'dashboard_app.testcase': {
-            'Meta': {'unique_together': "(('test', 'test_case_id'),)", 'object_name': 'TestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_cases'", 'to': "orm['dashboard_app.Test']"}),
-            'test_case_id': ('django.db.models.fields.TextField', [], {}),
-            'units': ('django.db.models.fields.TextField', [], {'blank': 'True'})
-        },
-        'dashboard_app.testdefinition': {
-            'Meta': {'object_name': 'TestDefinition'},
-            'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
-            'description': ('django.db.models.fields.TextField', [], {}),
-            'environment': ('django.db.models.fields.CharField', [], {'max_length': '256'}),
-            'format': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'location': ('django.db.models.fields.CharField', [], {'default': "'LOCAL'", 'max_length': '64'}),
-            'mime_type': ('django.db.models.fields.CharField', [], {'default': "'text/plain'", 'max_length': '64'}),
-            'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '512'}),
-            'target_dev_types': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'target_os': ('django.db.models.fields.CharField', [], {'max_length': '512'}),
-            'url': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'version': ('django.db.models.fields.CharField', [], {'max_length': '256'})
-        },
-        'dashboard_app.testresult': {
-            'Meta': {'ordering': "('_order',)", 'object_name': 'TestResult'},
-            '_order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'filename': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'lineno': ('django.db.models.fields.PositiveIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'measurement': ('django.db.models.fields.DecimalField', [], {'null': 'True', 'max_digits': '20', 'decimal_places': '10', 'blank': 'True'}),
-            'message': ('django.db.models.fields.TextField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'relative_index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'result': ('django.db.models.fields.PositiveSmallIntegerField', [], {}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'test_results'", 'null': 'True', 'to': "orm['dashboard_app.TestCase']"}),
-            'test_run': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_results'", 'to': "orm['dashboard_app.TestRun']"}),
-            'timestamp': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
-        },
-        'dashboard_app.testrun': {
-            'Meta': {'ordering': "['-import_assigned_date']", 'object_name': 'TestRun'},
-            'analyzer_assigned_date': ('django.db.models.fields.DateTimeField', [], {}),
-            'analyzer_assigned_uuid': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '36'}),
-            'bundle': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Bundle']"}),
-            'devices': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.HardwareDevice']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'import_assigned_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
-            'microseconds': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'blank': 'True'}),
-            'packages': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwarePackage']"}),
-            'sources': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.SoftwareSource']"}),
-            'sw_image_desc': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
-            'tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'test_runs'", 'blank': 'True', 'to': "orm['dashboard_app.Tag']"}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'test_runs'", 'to': "orm['dashboard_app.Test']"}),
-            'time_check_performed': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
-        },
-        'dashboard_app.testrundenormalization': {
-            'Meta': {'object_name': 'TestRunDenormalization'},
-            'count_fail': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_pass': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_skip': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'count_unknown': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test_run': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'denormalization'", 'unique': 'True', 'primary_key': 'True', 'to': "orm['dashboard_app.TestRun']"})
-        },
-        'dashboard_app.testrunfilter': {
-            'Meta': {'unique_together': "(('owner', 'name'),)", 'object_name': 'TestRunFilter'},
-            'build_number_attribute': ('django.db.models.fields.CharField', [], {'max_length': '1024', 'null': 'True', 'blank': 'True'}),
-            'bundle_streams': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['dashboard_app.BundleStream']", 'symmetrical': 'False'}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.SlugField', [], {'max_length': '1024'}),
-            'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
-            'public': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
-            'uploaded_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfilterattribute': {
-            'Meta': {'object_name': 'TestRunFilterAttribute'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attributes'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'name': ('django.db.models.fields.CharField', [], {'max_length': '1024'}),
-            'value': ('django.db.models.fields.CharField', [], {'max_length': '1024'})
-        },
-        'dashboard_app.testrunfiltersubscription': {
-            'Meta': {'unique_together': "(('user', 'filter'),)", 'object_name': 'TestRunFilterSubscription'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'level': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
-            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
-        },
-        'dashboard_app.testrunfiltertest': {
-            'Meta': {'object_name': 'TestRunFilterTest'},
-            'filter': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tests'", 'to': "orm['dashboard_app.TestRunFilter']"}),
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.Test']"})
-        },
-        'dashboard_app.testrunfiltertestcase': {
-            'Meta': {'object_name': 'TestRunFilterTestCase'},
-            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
-            'index': ('django.db.models.fields.PositiveIntegerField', [], {}),
-            'test': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'cases'", 'to': "orm['dashboard_app.TestRunFilterTest']"}),
-            'test_case': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'+'", 'to': "orm['dashboard_app.TestCase']"})
-        }
-    }
-
-    complete_apps = ['dashboard_app']
\ No newline at end of file

=== removed file 'dashboard_app/migrations/__init__.py'
=== removed file 'dashboard_app/models.py'
--- dashboard_app/models.py	2013-09-13 14:16:05 +0000
+++ dashboard_app/models.py	1970-01-01 00:00:00 +0000
@@ -1,1964 +0,0 @@
-# Copyright (C) 2010, 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Database models of the Dashboard application
-"""
-
-import datetime
-import errno
-import gzip
-import hashlib
-import logging
-import os
-import simplejson
-import traceback
-import contextlib
-
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.contrib.contenttypes import generic
-from django.contrib.contenttypes.models import ContentType
-from django.contrib.sites.models import Site
-from django.core.exceptions import ImproperlyConfigured, ValidationError
-from django.core.files import locks, File
-from django.core.files.storage import FileSystemStorage
-from django.core.mail import send_mail
-from django.core.urlresolvers import reverse
-from django.db import models
-from django.db.models.fields import FieldDoesNotExist
-from django.db.models.signals import post_delete
-from django.dispatch import receiver
-from django.template import Template, Context
-from django.template.defaultfilters import filesizeformat
-from django.template.loader import render_to_string
-from django.utils.translation import ugettext as _
-from django.utils.translation import ungettext
-
-from django_restricted_resource.models  import RestrictedResource
-from linaro_dashboard_bundle.io import DocumentIO
-
-from dashboard_app.helpers import BundleDeserializer
-from dashboard_app.managers import BundleManager, TestRunDenormalizationManager
-from dashboard_app.repositories import RepositoryItem
-from dashboard_app.repositories.data_report import DataReportRepository
-from dashboard_app.repositories.data_view import DataViewRepository
-from dashboard_app.signals import bundle_was_deserialized
-
-
-# Fix some django issues we ran into
-from dashboard_app.patches import patch
-patch()
-
-
-def _help_max_length(max_length):
-    return ungettext(
-            u"Maximum length: {0} character",
-            u"Maximum length: {0} characters",
-            max_length).format(max_length)
-
-
-class SoftwarePackage(models.Model):
-    """
-    Model for software packages.
-    """
-    name = models.CharField(
-            max_length = 128,
-            verbose_name = _(u"Package name"),
-            help_text = _help_max_length(128))
-
-    version = models.CharField(
-            max_length = 128,
-            verbose_name = _(u"Package version"),
-            help_text = _help_max_length(128))
-
-    class Meta:
-        unique_together = (('name', 'version'))
-
-    def __unicode__(self):
-        return _(u"{name} {version}").format(
-                name = self.name,
-                version = self.version)
-
-    @property
-    def link_to_packages_ubuntu_com(self):
-        return u"http://packages.ubuntu.com/{name}".format(name=self.name)
-
-
-class SoftwarePackageScratch(models.Model):
-    """
-    Staging area for SoftwarePackage data.
-
-    The code that keeps SoftwarePackage dumps data into here before more
-    carefully inserting it into the real SoftwarePackage table.
-
-    No data should ever be committed in this table.  It would be a temporary
-    table, but oddities in how the sqlite DB-API wrapper handles transactions
-    makes this impossible.
-    """
-    name = models.CharField(max_length=128)
-    version = models.CharField(max_length=128)
-
-
-class NamedAttribute(models.Model):
-    """
-    Model for adding generic named attributes
-    to arbitrary other model instances.
-
-    Example:
-        class Foo(Model):
-            attributes = generic.GenericRelation(NamedAttribute)
-    """
-    name = models.TextField()
-
-    value = models.TextField()
-
-    # Content type plumbing
-    content_type = models.ForeignKey(ContentType)
-    object_id = models.PositiveIntegerField()
-    content_object = generic.GenericForeignKey('content_type', 'object_id')
-
-    def __unicode__(self):
-        return _(u"{name}: {value}").format(
-                name = self.name,
-                value = self.value)
-
-    class Meta:
-        unique_together = (('object_id', 'name'))
-
-
-class HardwareDevice(models.Model):
-    """
-    Model for hardware devices
-
-    All devices are simplified into an instance of pre-defined class
-    with arbitrary key-value attributes.
-    """
-    device_type = models.CharField(
-            choices = (
-                (u"device.cpu", _(u"CPU")),
-                (u"device.mem", _(u"Memory")),
-                (u"device.usb", _(u"USB device")),
-                (u"device.pci", _(u"PCI device")),
-                (u"device.board", _(u"Board/Motherboard"))),
-            help_text = _(u"One of pre-defined device types"),
-            max_length = 32,
-            verbose_name = _(u"Device Type"),
-            )
-
-    description = models.CharField(
-            help_text = _(u"Human readable device summary.") + " " + _help_max_length(256),
-            max_length = 256,
-            verbose_name = _(u"Description"),
-            )
-
-    attributes = generic.GenericRelation(NamedAttribute)
-
-    def __unicode__(self):
-        return self.description
-
-
-class BundleStream(RestrictedResource):
-    """
-    Model for "streams" of bundles.
-
-    Basically it's a named collection of bundles, like directory just
-    without the nesting. A simple ACL scheme is also supported,
-    a bundle may be uploaded by:
-        - specific user when user field is set
-        - users of a specific group when group field is set
-        - anyone when neither user nor group is set
-    """
-    PATHNAME_ANONYMOUS = "anonymous"
-    PATHNAME_PUBLIC = "public"
-    PATHNAME_PRIVATE = "private"
-    PATHNAME_PERSONAL = "personal"
-    PATHNAME_TEAM = "team"
-
-    slug = models.CharField(
-            blank = True,
-            help_text = (_(u"Name that you will use when uploading bundles.")
-                + " " + _help_max_length(64)),
-            max_length = 64,
-            verbose_name = _(u"Slug"),
-            )
-
-    name = models.CharField(
-            blank = True,
-            help_text = _help_max_length(64),
-            max_length = 64,
-            verbose_name = _(u"Name"),
-            )
-
-    pathname = models.CharField(
-            max_length = 128,
-            editable = False,
-            unique = True,
-            )
-
-    is_anonymous = models.BooleanField()
-
-    def __unicode__(self):
-        return self.pathname
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.bundle_list", [self.pathname])
-
-    def get_test_run_count(self):
-        return TestRun.objects.filter(bundle__bundle_stream=self).count()
-
-    def clean(self):
-        if self.is_anonymous and not self.is_public:
-            raise ValidationError(
-                'Anonymous streams must be public')
-        return super(BundleStream, self).clean()
-
-    def save(self, *args, **kwargs):
-        """
-        Save this instance.
-
-        Calls self.clean() to ensure that constraints are met.
-        Updates pathname to reflect user/group/slug changes.
-        """
-        self.pathname = self._calc_pathname()
-        self.clean()
-        return super(BundleStream, self).save(*args, **kwargs)
-
-    def _calc_pathname(self):
-        """
-        Pseudo pathname-like ID of this stream.
-
-        This pathname is user visible and will be presented to users
-        when they want to interact with this bundle stream. The
-        pathnames are unique and this is enforced at database level (the
-        user and name are unique together).
-        """
-        if self.is_anonymous:
-            parts = ['', self.PATHNAME_ANONYMOUS]
-        else:
-            if self.is_public:
-                parts = ['', self.PATHNAME_PUBLIC]
-            else:
-                parts = ['', self.PATHNAME_PRIVATE]
-            if self.user is not None:
-                parts.append(self.PATHNAME_PERSONAL)
-                parts.append(self.user.username)
-            elif self.group is not None:
-                parts.append(self.PATHNAME_TEAM)
-                parts.append(self.group.name)
-        if self.slug:
-            parts.append(self.slug)
-        parts.append('')
-        return u"/".join(parts)
-
-    @classmethod
-    def parse_pathname(cls, pathname):
-        """
-        Parse BundleStream pathname.
-
-        Returns user, group, slug, is_public, is_anonymous
-        Raises ValueError if the pathname is not well formed
-        """
-        if not pathname.endswith('/'):
-            pathname = pathname + '/'
-        pathname_parts = pathname.split('/')
-        if len(pathname_parts) < 3:
-            raise ValueError("Pathname too short: %r" % pathname)
-        if pathname_parts[0] != '':
-            raise ValueError("Pathname must be absolute: %r" % pathname)
-        if pathname_parts[1] == cls.PATHNAME_ANONYMOUS:
-            user = None
-            group = None
-            slug = pathname_parts[2]
-            correct_length = 2
-            is_anonymous = True
-            is_public = True
-        else:
-            is_anonymous = False
-            if pathname_parts[1] == cls.PATHNAME_PUBLIC:
-                is_public = True
-            elif pathname_parts[1] == cls.PATHNAME_PRIVATE:
-                is_public = False
-            else:
-                raise ValueError("Invalid pathname privacy designator:"
-                        " %r (full pathname: %r)" % (pathname_parts[1],
-                            pathname))
-            if pathname_parts[2] == cls.PATHNAME_PERSONAL:
-                if len(pathname_parts) < 4:
-                    raise ValueError("Pathname too short: %r" % pathname)
-                user = pathname_parts[3]
-                group = None
-                slug = pathname_parts[4]
-                correct_length = 4
-            elif pathname_parts[2] == cls.PATHNAME_TEAM:
-                if len(pathname_parts) < 4:
-                    raise ValueError("Pathname too short: %r" % pathname)
-                user = None
-                group = pathname_parts[3]
-                slug = pathname_parts[4]
-                correct_length = 4
-            else:
-                raise ValueError("Invalid pathname ownership designator:"
-                        " %r (full pathname %r)" % (pathname[2],
-                            pathname))
-        if slug != '':
-            correct_length += 1
-        if pathname_parts[correct_length:] != ['']:
-            raise ValueError("Junk after pathname: %r" % pathname)
-        return user, group, slug, is_public, is_anonymous
-
-    def can_upload(self, user):
-        """
-        Return True if the user can upload bundles here
-        """
-        return self.is_anonymous or self.is_owned_by(user)
-
-
-class GzipFileSystemStorage(FileSystemStorage):
-
-    def _open(self, name, mode='rb'):
-        full_path = self.path(name)
-        gzip_file = gzip.GzipFile(full_path, mode)
-        gzip_file.name = full_path
-        return File(gzip_file)
-
-    # This is a copy-paste-hack of FileSystemStorage._save
-    def _save(self, name, content):
-        full_path = self.path(name)
-
-        directory = os.path.dirname(full_path)
-        if not os.path.exists(directory):
-            os.makedirs(directory)
-        elif not os.path.isdir(directory):
-            raise IOError("%s exists and is not a directory." % directory)
-
-        # There's a potential race condition between get_available_name and
-        # saving the file; it's possible that two threads might return the
-        # same name, at which point all sorts of fun happens. So we need to
-        # try to create the file, but if it already exists we have to go back
-        # to get_available_name() and try again.
-
-        while True:
-            try:
-                # This fun binary flag incantation makes os.open throw an
-                # OSError if the file already exists before we open it.
-                fd = os.open(full_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, 'O_BINARY', 0))
-                # This line, and the use of gz_file.write below, are the
-                # changes from the original version of this.
-                gz_file = gzip.GzipFile(fileobj=os.fdopen(fd, 'wb'))
-                try:
-                    locks.lock(fd, locks.LOCK_EX)
-                    for chunk in content.chunks():
-                        gz_file.write(chunk)
-                finally:
-                    locks.unlock(fd)
-                    gz_file.close()
-            except OSError, e:
-                if e.errno == errno.EEXIST:
-                    # Ooops, the file exists. We need a new file name.
-                    name = self.get_available_name(name)
-                    full_path = self.path(name)
-                else:
-                    raise
-            else:
-                # OK, the file save worked. Break out of the loop.
-                break
-
-        if settings.FILE_UPLOAD_PERMISSIONS is not None:
-            os.chmod(full_path, settings.FILE_UPLOAD_PERMISSIONS)
-
-        return name
-
-
-class Bundle(models.Model):
-    """
-    Model for "Dashboard Bundles"
-    """
-    bundle_stream = models.ForeignKey(BundleStream,
-            verbose_name = _(u"Stream"),
-            related_name = 'bundles')
-
-    uploaded_by = models.ForeignKey(User,
-            verbose_name = _(u"Uploaded by"),
-            help_text = _(u"The user who submitted this bundle"),
-            related_name = 'uploaded_bundles',
-            null = True,
-            blank = True)
-
-    uploaded_on = models.DateTimeField(
-            verbose_name = _(u"Uploaded on"),
-            editable = False,
-            default = datetime.datetime.utcnow)
-
-    is_deserialized = models.BooleanField(
-            verbose_name = _(u"Is deserialized"),
-            help_text = _(u"Set when document has been analyzed and loaded"
-                " into the database"),
-            editable = False)
-
-    _raw_content = models.FileField(
-            verbose_name = _(u"Content"),
-            help_text = _(u"Document in Dashboard Bundle Format 1.0"),
-            upload_to = 'bundles',
-            null = True,
-            db_column = 'content')
-
-    _gz_content = models.FileField(
-            verbose_name = _(u"Compressed content"),
-            help_text = _(u"Compressed document in Dashboard Bundle Format 1.0"),
-            upload_to = 'compressed-bundles',
-            null = True,
-            db_column = 'gz_content',
-            storage = GzipFileSystemStorage())
-
-    def _get_content(self):
-        r = self._gz_content
-        if not r:
-            return self._raw_content
-        else:
-            return r
-
-    content = property(_get_content)
-
-    def compress(self):
-        c = self._raw_content
-        self._gz_content.save(c.name, c)
-        c.delete()
-
-    content_sha1 = models.CharField(
-            editable = False,
-            max_length = 40,
-            null = True,
-            unique = True)
-
-    content_filename = models.CharField(
-            verbose_name = _(u"Content file name"),
-            help_text = _(u"Name of the originally uploaded bundle"),
-            max_length = 256)
-
-    objects = BundleManager()
-
-    def __unicode__(self):
-        return _(u"Bundle {0}").format(self.content_sha1)
-
-    class Meta:
-        ordering = ['-uploaded_on']
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.bundle_detail", [self.bundle_stream.pathname, self.content_sha1])
-
-    def get_permalink(self):
-        return reverse("dashboard_app.views.redirect_to_bundle", args=[self.content_sha1])
-
-    def save(self, *args, **kwargs):
-        if self.content:
-            try:
-                self.content.open('rb')
-                sha1 = hashlib.sha1()
-                for chunk in self.content.chunks():
-                    sha1.update(chunk)
-                self.content_sha1 = sha1.hexdigest()
-            finally:
-                self.content.close()
-        return super(Bundle, self).save(*args, **kwargs)
-
-    def deserialize(self, prefer_evolution=False):
-        """
-        Deserialize the contents of this bundle.
-
-        The actual implementation is _do_serialize() this function
-        catches any exceptions it might throw and converts them to
-        BundleDeserializationError instance. Any previous import errors are
-        overwritten.
-
-        Successful import also discards any previous import errors and
-        sets is_deserialized to True.
-        """
-        if self.is_deserialized:
-            return
-        try:
-            self._do_deserialize(prefer_evolution)
-        except Exception as ex:
-            import_error = BundleDeserializationError.objects.get_or_create(
-                bundle=self)[0]
-            import_error.error_message = str(ex)
-            import_error.traceback = traceback.format_exc()
-            import_error.save()
-        else:
-            try:
-                self.deserialization_error.delete()
-            except BundleDeserializationError.DoesNotExist:
-                pass
-            self.is_deserialized = True
-            self.save()
-            bundle_was_deserialized.send_robust(sender=self, bundle=self)
-
-    def _do_deserialize(self, prefer_evolution):
-        """
-        Deserialize this bundle or raise an exception
-        """
-        helper = BundleDeserializer()
-        helper.deserialize(self, prefer_evolution)
-
-    def get_summary_results(self):
-        if self.is_deserialized:
-            stats = TestResult.objects.filter(
-                test_run__bundle = self).values(
-                    'result').annotate(
-                        count=models.Count('result'))
-            result = dict([
-                (TestResult.RESULT_MAP[item['result']], item['count'])
-                for item in stats])
-            result['total'] = sum(result.values())
-            return result
-
-    def delete_files(self, save=False):
-        """
-        Delete all files related to this bundle.
-
-        This is currently used in test code to clean up after testing.
-        """
-        self.content.delete(save=save)
-        for test_run in self.test_runs.all():
-            for attachment in test_run.attachments.all():
-                attachment.content.delete(save=save)
-
-    def get_sanitized_bundle(self):
-        self.content.open()
-        try:
-            return SanitizedBundle(self.content)
-        finally:
-            self.content.close()
-
-    def get_document_format(self):
-        try:
-            self.content.open('rb')
-        except IOError:
-            return "unknown"
-        else:
-            try:
-                fmt, doc = DocumentIO.load(self.content)
-                return fmt
-            finally:
-                self.content.close()
-
-    def get_serialization_format(self):
-        return "JSON"
-
-    def get_content_size(self):
-        try:
-            return filesizeformat(self.content.size)
-        except OSError:
-            return "unknown"
-
-
-class SanitizedBundle(object):
-
-    def __init__(self, stream):
-        try:
-            self.bundle_json = simplejson.load(stream)
-            self.deserialization_error = None
-        except simplejson.JSONDeserializationError as ex:
-            self.bundle_json = None
-            self.deserialization_error = ex
-        self.did_remove_attachments = False
-        self._sanitize()
-
-    def get_human_readable_json(self):
-        return simplejson.dumps(self.bundle_json, indent=4)
-
-    def _sanitize(self):
-        for test_run in self.bundle_json.get("test_runs", []):
-            attachments = test_run.get("attachments")
-            if isinstance(attachments, list):
-                for attachment in attachments:
-                    attachment["content"] = None
-                    self.did_remove_attachments = True
-            elif isinstance(attachments, dict):
-                for name in attachments:
-                    attachments[name] = None
-                    self.did_remove_attachments = True
-
-
-class BundleDeserializationError(models.Model):
-    """
-    Model for representing errors encountered during bundle
-    deserialization. There is one instance per bundle limit due to
-    unique = True. There used to be a OneToOne field but it didn't work
-    with databrowse application.
-
-    The relevant logic for managing this is in the Bundle.deserialize()
-    """
-
-    bundle = models.OneToOneField(
-        Bundle,
-        primary_key = True,
-        unique = True,
-        related_name = 'deserialization_error'
-    )
-
-    error_message = models.CharField(
-        max_length = 1024
-    )
-
-    traceback = models.TextField(
-        max_length = 1 << 15,
-    )
-
-    def __unicode__(self):
-        return self.error_message
-
-
-class Test(models.Model):
-    """
-    Model for representing tests.
-
-    Test is a collection of individual test cases.
-    """
-    test_id = models.CharField(
-        max_length = 1024,
-        verbose_name = _("Test ID"),
-        unique = True)
-
-    name = models.CharField(
-        blank = True,
-        max_length = 1024,
-        verbose_name = _(u"Name"))
-
-    def __unicode__(self):
-        return self.name or self.test_id
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ('dashboard_app.views.test_detail', [self.test_id])
-
-    def count_results_without_test_case(self):
-        return TestResult.objects.filter(
-            test_run__test=self,
-            test_case=None).count()
-
-    def count_failures_without_test_case(self):
-        return TestResult.objects.filter(
-            test_run__test=self,
-            test_case=None,
-            result=TestResult.RESULT_FAIL).count()
-
-
-class TestCase(models.Model):
-    """
-    Model for representing test cases.
-
-    Test case is a unique component of a specific test.
-    Test cases allow for relating to test results.
-    """
-    test = models.ForeignKey(
-        Test,
-        related_name='test_cases')
-
-    test_case_id = models.TextField(
-        verbose_name = _("Test case ID"))
-
-    name = models.TextField(
-        blank = True,
-        help_text = _help_max_length(100),
-        verbose_name = _("Name"))
-
-    units = models.TextField(
-        blank = True,
-        help_text = (_("""Units in which measurement value should be
-                       interpreted in, for example <q>ms</q>, <q>MB/s</q> etc.
-                       There is no semantical meaning inferred from the value of
-                       this field, free form text is allowed. <br/>""")
-                     + _help_max_length(100)),
-        verbose_name = _("Units"))
-
-    class Meta:
-        unique_together = (('test', 'test_case_id'))
-
-    def __unicode__(self):
-        return self.name or self.test_case_id
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.test_case.details", [self.test.test_id, self.test_case_id])
-
-    def count_failures(self):
-        return self.test_results.filter(result=TestResult.RESULT_FAIL).count()
-
-
-class TestDefinition(models.Model):
-    """
-    Model for representing test definitions.
-
-    Test Definition are in YAML format.
-    """
-    LOCATION_CHOICES = (
-        ('LOCAL', 'Local'),
-        ('URL', 'URL'),
-        ('GIT', 'GIT Repo'),
-        ('BZR', 'BZR Repo'),
-        )
-
-    name = models.CharField(
-        max_length = 512,
-        verbose_name = _("Name"),
-        unique = True,
-        help_text = _help_max_length(512))
-
-    version = models.CharField(
-        max_length=256,
-        verbose_name = _("Version"),
-        help_text = _help_max_length(256))
-
-    description = models.TextField(
-        verbose_name = _("Description"))
-
-    format = models.CharField(
-        max_length = 128,
-        verbose_name = _("Format"),
-        help_text = _help_max_length(128))
-
-    location = models.CharField(
-        max_length = 64,
-        verbose_name = _("Location"),
-        choices = LOCATION_CHOICES,
-        default = 'LOCAL')
-
-    url = models.CharField(
-        verbose_name = _(u"URL"),
-        max_length = 1024,
-        blank = False,
-        help_text = _help_max_length(1024))
-
-    environment = models.CharField(
-        max_length = 256,
-        verbose_name = _("Environment"),
-        help_text = _help_max_length(256))
-
-    target_os = models.CharField(
-        max_length = 512,
-        verbose_name = _("Operating Systems"),
-        help_text = _help_max_length(512))
-
-    target_dev_types = models.CharField(
-        max_length = 512,
-        verbose_name = _("Device types"),
-        help_text = _help_max_length(512))
-
-    content = models.FileField(
-        verbose_name = _(u"Upload Test Definition"),
-        help_text = _(u"Test definition file"),
-        upload_to = 'testdef',
-        blank = True,
-        null = True)
-
-    mime_type = models.CharField(
-        verbose_name = _(u"MIME type"),
-        default = 'text/plain',
-        max_length = 64,
-        help_text = _help_max_length(64))
-
-    def __unicode__(self):
-        return self.name
-
-
-class SoftwareSource(models.Model):
-    """
-    Model for representing source reference of a particular project
-    """
-
-    project_name = models.CharField(
-        max_length = 32,
-        help_text = _help_max_length(32),
-        verbose_name = _(u"Project Name"),
-    )
-    branch_url = models.CharField(
-        max_length = 256,
-        help_text = _help_max_length(256),
-        verbose_name = _(u"Branch URL"),
-    )
-    branch_vcs = models.CharField(
-        max_length = 10,
-        help_text = _help_max_length(10),
-        verbose_name = _(u"Branch VCS"),
-    )
-    branch_revision = models.CharField(
-        max_length = 128,
-        help_text = _help_max_length(128),
-        verbose_name = _(u"Branch Revision")
-    )
-    commit_timestamp = models.DateTimeField(
-        blank=True,
-        null=True,
-        help_text = _(u"Date and time of the commit (optional)"),
-        verbose_name = _(u"Commit Timestamp")
-    )
-
-    def __unicode__(self):
-        return _(u"{project_name} from branch {branch_url} at revision {branch_revision}").format(
-            project_name=self.project_name, branch_url=self.branch_url, branch_revision=self.branch_revision)
-
-    @property
-    def is_hosted_on_launchpad(self):
-        return self.branch_url.startswith("lp:")
-
-    @property
-    def is_tag_revision(self):
-        return self.branch_revision.startswith("tag:")
-
-    @property
-    def branch_tag(self):
-        if self.is_tag_revision:
-            return self.branch_revision[len("tag:"):]
-
-    @property
-    def link_to_project(self):
-        return "http://launchpad.net/{project_name}".format(project_name=self.project_name)
-
-    @property
-    def link_to_branch(self):
-        if self.is_hosted_on_launchpad:
-            return "http://launchpad.net/{branch_url}/".format(branch_url=self.branch_url[len("lp:"):])
-
-class TestRun(models.Model):
-    """
-    Model for representing test runs.
-
-    Test run is an act of running a Test in a certain context. The
-    context is described by the software and hardware environment.  In
-    addition to those properties each test run can have arbitrary named
-    properties for additional context that is not reflected in the
-    database directly.
-
-    Test runs have global identity exists beyond the lifetime of
-    bundle that essentially encapsulates test run information should
-    store the UUID that was generated at the time the document is made.
-    the dashboard application. The software that prepares the dashboard
-    """
-
-    # Meta-data
-
-    bundle = models.ForeignKey(
-        Bundle,
-        related_name = 'test_runs',
-    )
-
-    test = models.ForeignKey(
-        Test,
-        related_name = 'test_runs',
-    )
-
-    analyzer_assigned_uuid = models.CharField(
-        help_text = _(u"You can use uuid.uuid1() to generate a value"),
-        max_length = 36,
-        unique = True,
-        verbose_name = _(u"Analyzer assigned UUID"),
-    )
-
-    analyzer_assigned_date = models.DateTimeField(
-        verbose_name = _(u"Analyzer assigned date"),
-        help_text = _(u"Time stamp when the log was processed by the log"
-                      " analyzer"),
-    )
-
-    import_assigned_date = models.DateTimeField(
-        verbose_name = _(u"Import assigned date"),
-        help_text = _(u"Time stamp when the bundle was imported"),
-        auto_now_add = True,
-    )
-
-    time_check_performed = models.BooleanField(
-        verbose_name = _(u"Time check performed"),
-        help_text = _(u"Indicator on wether timestamps in the log file (and any "
-                      "data derived from them) should be trusted.<br/>"
-                      "Many pre-production or development devices do not "
-                      "have a battery-powered RTC and it's not common for "
-                      "development images not to synchronize time with "
-                      "internet time servers.<br/>"
-                      "This field allows us to track tests results that "
-                      "<em>certainly</em> have correct time if we ever end up "
-                      "with lots of tests results from 1972")
-    )
-
-    microseconds = models.BigIntegerField(
-        blank = True,
-        null = True
-    )
-
-    # Software Context
-
-    sw_image_desc = models.CharField(
-        blank = True,
-        max_length = 100,
-        verbose_name = _(u"Operating System Image"),
-    )
-
-    packages = models.ManyToManyField(
-        SoftwarePackage,
-        blank = True,
-        related_name = 'test_runs',
-        verbose_name = _(u"Software packages"),
-    )
-
-    sources = models.ManyToManyField(
-        SoftwareSource,
-        blank = True,
-        related_name = 'test_runs',
-        verbose_name = _(u"Software sources"),
-    )
-
-    # Hardware Context
-
-    devices = models.ManyToManyField(
-        HardwareDevice,
-        blank = True,
-        related_name = 'test_runs',
-        verbose_name = _(u"Hardware devices"),
-    )
-
-    # Attributes
-
-    attributes = generic.GenericRelation(NamedAttribute)
-
-    # Tags
-
-    tags = models.ManyToManyField(
-        "Tag",
-        blank=True,
-        related_name='test_runs',
-        verbose_name=_(u"Tags"))
-
-    # Attachments
-
-    attachments = generic.GenericRelation('Attachment')
-
-    def __unicode__(self):
-        return _(u"Test run {0}").format(self.analyzer_assigned_uuid)
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.test_run_detail",
-                [self.bundle.bundle_stream.pathname,
-                 self.bundle.content_sha1,
-                 self.analyzer_assigned_uuid])
-
-    def get_permalink(self):
-        return reverse("dashboard_app.views.redirect_to_test_run", args=[self.analyzer_assigned_uuid])
-
-    def get_board(self):
-        """
-        Return an associated Board device, if any.
-        """
-        try:
-            return self.devices.filter(device_type="device.board").get()
-        except HardwareDevice.DoesNotExist:
-            pass
-        except HardwareDevice.MultipleObjectsReturned:
-            pass
-
-    def get_results(self):
-        """
-        Get all results efficiently
-        """
-        return self.test_results.select_related(
-            "test_case",  # explicit join on test_case which might be NULL
-            "test_run",  # explicit join on test run, needed by all the get_absolute_url() methods
-            "test_run__bundle",  # explicit join on bundle
-            "test_run__bundle__bundle_stream",  # explicit join on bundle stream
-        ).order_by("relative_index")  # sort as they showed up in the bundle
-
-    def denormalize(self):
-        try:
-            self.denormalization
-        except TestRunDenormalization.DoesNotExist:
-            TestRunDenormalization.objects.create_from_test_run(self)
-
-    def _get_summary_results(self, factor=3):
-        stats = self.test_results.values('result').annotate(
-            count=models.Count('result')).order_by()
-        result = dict([
-            (TestResult.RESULT_MAP[item['result']], item['count'])
-            for item in stats])
-        result['total'] = sum(result.values())
-        result['total_multiplied'] = result['total'] * factor
-        return result
-
-    def get_summary_results(self):
-        if not hasattr(self, '_cached_summary_results'):
-            self._cached_summary_results = self._get_summary_results()
-        return self._cached_summary_results
-
-    # test_duration property
-
-    def _get_test_duration(self):
-        if self.microseconds is None:
-            return None
-        else:
-            return datetime.timedelta(microseconds = self.microseconds)
-
-    def _set_test_duration(self, duration):
-        if duration is None:
-            self.microseconds = None
-        else:
-            if not isinstance(duration, datetime.timedelta):
-                raise TypeError("duration must be a datetime.timedelta() instance")
-            self.microseconds = (
-                duration.microseconds +
-                (duration.seconds * 10 ** 6) +
-                (duration.days * 24 * 60 * 60 * 10 ** 6))
-
-    test_duration = property(_get_test_duration, _set_test_duration)
-
-    class Meta:
-        ordering = ['-import_assigned_date']
-
-    def show_device(self):
-        all_attributes = self.attributes.all()
-        for one_attributes in all_attributes:
-            if one_attributes.name == "target":
-                return one_attributes.value
-
-        for one_attributes in all_attributes:
-            if one_attributes.name == "target.hostname":
-                return one_attributes.value
-
-        for one_attributes in all_attributes:
-            if one_attributes.name == "target.device_type":
-                return one_attributes.value
-        return "Target Device"
-
-
-class TestRunDenormalization(models.Model):
-    """
-    Denormalized model for test run
-    """
-
-    test_run = models.OneToOneField(
-        TestRun,
-        primary_key=True,
-        related_name="denormalization")
-
-    count_pass = models.PositiveIntegerField(
-        null=False,
-        blank=False)
-
-    count_fail = models.PositiveIntegerField(
-        null=False,
-        blank=False)
-
-    count_skip = models.PositiveIntegerField(
-        null=False,
-        blank=False)
-
-    count_unknown = models.PositiveIntegerField(
-        null=False,
-        blank=False)
-
-    def count_all(self):
-        return (self.count_pass + self.count_fail + self.count_skip +
-                self.count_unknown)
-
-    objects = TestRunDenormalizationManager()
-
-
-class Attachment(models.Model):
-    """
-    Model for adding attachments to any other models.
-    """
-
-    content = models.FileField(
-        verbose_name = _(u"Content"),
-        help_text = _(u"Attachment content"),
-        upload_to = 'attachments',
-        null = True)
-
-    content_filename = models.CharField(
-        verbose_name = _(u"Content file name"),
-        help_text = _(u"Name of the original attachment"),
-        max_length = 256)
-
-    mime_type = models.CharField(
-        verbose_name = _(u"MIME type"),
-        max_length = 64)
-
-    public_url = models.URLField(
-        verbose_name = _(u"Public URL"),
-        max_length = 512,
-        blank = True)
-
-    # Content type plumbing
-    content_type = models.ForeignKey(ContentType)
-    object_id = models.PositiveIntegerField()
-    content_object = generic.GenericForeignKey('content_type', 'object_id')
-
-    def __unicode__(self):
-        return self.content_filename
-
-    def is_test_run_attachment(self):
-        if (self.content_type.app_label == 'dashboard_app' and
-            self.content_type.model == 'testrun'):
-            return True
-
-    def is_test_result_attachment(self):
-        if (self.content_type.app_label == 'dashboard_app' and
-            self.content_type.model == 'testresult'):
-            return True
-
-    @property
-    def test_run(self):
-        if self.is_test_run_attachment():
-            return self.content_object
-
-    @property
-    def test_result(self):
-        if self.is_test_result_attachment():
-            return self.content_object
-
-    @property
-    def bundle(self):
-        if self.is_test_result_attachment():
-            run = self.test_result.test_run
-        elif self.is_test_run_attachment():
-            run = self.test_run
-        return run.bundle
-
-    def get_content_size(self):
-        try:
-            return filesizeformat(self.content.size)
-        except OSError:
-            return "unknown size"
-
-    @models.permalink
-    def get_download_url(self):
-        return ("dashboard_app.views.attachment_download",
-                [self.pk])
-
-    @models.permalink
-    def get_view_url(self):
-        return ("dashboard_app.views.attachment_view",
-                [self.pk])
-
-    def is_viewable(self):
-        return self.mime_type in ['text/plain']
-
-
-class TestResult(models.Model):
-    """
-    Model for representing test results.
-    """
-
-    RESULT_PASS = 0
-    RESULT_FAIL = 1
-    RESULT_SKIP = 2
-    RESULT_UNKNOWN = 3
-
-    RESULT_MAP = {
-        RESULT_PASS: 'pass',
-        RESULT_FAIL: 'fail',
-        RESULT_SKIP: 'skip',
-        RESULT_UNKNOWN: 'unknown'
-    }
-
-    # Context information
-
-    test_run = models.ForeignKey(
-        TestRun,
-        related_name = "test_results"
-    )
-
-    test_case = models.ForeignKey(
-        TestCase,
-        related_name = "test_results",
-        null = True,
-        blank = True
-    )
-
-    @property
-    def test(self):
-        return self.test_run.test
-
-    # Core attributes
-
-    result = models.PositiveSmallIntegerField(
-        verbose_name = _(u"Result"),
-        help_text = _(u"Result classification to pass/fail group"),
-        choices = (
-            (RESULT_PASS, _(u"Test passed")),
-            (RESULT_FAIL, _(u"Test failed")),
-            (RESULT_SKIP, _(u"Test skipped")),
-            (RESULT_UNKNOWN, _(u"Unknown outcome")))
-    )
-
-    measurement = models.DecimalField(
-        blank = True,
-        decimal_places = 10,
-        help_text = _(u"Arbitrary value that was measured as a part of this test."),
-        max_digits = 20,
-        null = True,
-        verbose_name = _(u"Measurement"),
-    )
-
-    # Misc attributes
-
-    filename = models.CharField(
-        blank = True,
-        max_length = 1024,
-        null = True,
-    )
-
-    lineno = models.PositiveIntegerField(
-        blank = True,
-        null = True
-    )
-
-    message = models.TextField(
-        blank = True,
-        max_length = 1024,
-        null = True
-    )
-
-    microseconds = models.BigIntegerField(
-        blank = True,
-        null = True
-    )
-
-    timestamp = models.DateTimeField(
-        blank = True,
-        null = True
-    )
-
-    relative_index = models.PositiveIntegerField(
-        help_text = _(u"The relative order of test results in one test run")
-    )
-
-    def __unicode__(self):
-        return "Result {0}/{1}".format(self.test_run.analyzer_assigned_uuid, self.relative_index)
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.test_result_detail", [
-            self.test_run.bundle.bundle_stream.pathname,
-            self.test_run.bundle.content_sha1,
-            self.test_run.analyzer_assigned_uuid,
-            self.relative_index,
-        ])
-
-    def get_permalink(self):
-        return reverse("dashboard_app.views.redirect_to_test_result",
-                       args=[self.test_run.analyzer_assigned_uuid,
-                             self.relative_index])
-
-    @property
-    def result_code(self):
-        """
-        Stable textual result code that does not depend on locale
-        """
-        return self.RESULT_MAP[self.result]
-
-    # units (via test case)
-
-    @property
-    def units(self):
-        try:
-            return self.test_case.units
-        except TestCase.DoesNotExist:
-            return None
-
-    # Attributes
-
-    attributes = generic.GenericRelation(NamedAttribute)
-
-    # Attachments
-
-    attachments = generic.GenericRelation(Attachment)
-
-    # Duration property
-
-    def _get_duration(self):
-        if self.microseconds is None:
-            return None
-        else:
-            return datetime.timedelta(microseconds = self.microseconds)
-
-    def _set_duration(self, duration):
-        if duration is None:
-            self.microseconds = None
-        else:
-            if not isinstance(duration, datetime.timedelta):
-                raise TypeError("duration must be a datetime.timedelta() instance")
-            self.microseconds = (
-                duration.microseconds +
-                (duration.seconds * 10 ** 6) +
-                (duration.days * 24 * 60 * 60 * 10 ** 6))
-
-    duration = property(_get_duration, _set_duration)
-
-    def related_attachment_available(self):
-        """
-        Check if there is a log file attached to the test run that has
-        the same filename as log filename recorded in the result here.
-        """
-        try:
-            self.related_attachment()
-            return True
-        except Attachment.DoesNotExist:
-            return False
-
-    def related_attachment(self):
-        return self.test_run.attachments.get(content_filename=self.filename)
-
-    class Meta:
-        ordering = ['relative_index']
-        order_with_respect_to = 'test_run'
-
-
-class DataView(RepositoryItem):
-    """
-    Data view, a container for SQL query and optional arguments
-    """
-
-    repository = DataViewRepository()
-
-    def __init__(self, name, backend_queries, arguments, documentation, summary):
-        self.name = name
-        self.backend_queries = backend_queries
-        self.arguments = arguments
-        self.documentation = documentation
-        self.summary = summary
-
-    def __unicode__(self):
-        return self.name
-
-    def __repr__(self):
-        return "<DataView name=%r>" % (self.name,)
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.data_view_detail", [self.name])
-
-    def _get_connection_backend_name(self, connection):
-        backend = str(type(connection))
-        if "sqlite" in backend:
-            return "sqlite"
-        elif "postgresql" in backend:
-            return "postgresql"
-        else:
-            return ""
-
-    def get_backend_specific_query(self, connection):
-        """
-        Return BackendSpecificQuery for the specified connection
-        """
-        sql_backend_name = self._get_connection_backend_name(connection)
-        try:
-            return self.backend_queries[sql_backend_name]
-        except KeyError:
-            return self.backend_queries.get(None, None)
-
-    def lookup_argument(self, name):
-        """
-        Return Argument with the specified name
-
-        Raises LookupError if the argument cannot be found
-        """
-        for argument in self.arguments:
-            if argument.name == name:
-                return argument
-        raise LookupError(name)
-
-    @classmethod
-    def get_connection(cls):
-        """
-        Get the appropriate connection for data views
-        """
-        from django.db import connection, connections
-        from django.db.utils import ConnectionDoesNotExist
-        try:
-            return connections['dataview']
-        except ConnectionDoesNotExist:
-            logging.warning("dataview-specific database connection not available, dataview query is NOT sandboxed")
-            return connection  # NOTE: it's connection not connectionS (the default connection)
-
-    def __call__(self, connection, **arguments):
-        # Check if arguments have any bogus names
-        valid_arg_names = frozenset([argument.name for argument in self.arguments])
-        for arg_name in arguments:
-            if arg_name not in valid_arg_names:
-                raise TypeError("Data view %s has no argument %r" % (self.name, arg_name))
-        # Get the SQL template for our database connection
-        query = self.get_backend_specific_query(connection)
-        if query is None:
-            raise LookupError("Specified data view has no SQL implementation "
-                              "for current database")
-        # Replace SQL aruments with django placeholders (connection agnostic)
-        template = query.sql_template
-        template = template.replace("%", "%%")
-        # template = template.replace("{", "{{").replace("}", "}}")
-        sql = template.format(
-            **dict([
-                (arg_name, "%s")
-                for arg_name in query.argument_list]))
-        # Construct argument list using defaults for missing values
-        sql_args = [
-            arguments.get(arg_name, self.lookup_argument(arg_name).default)
-            for arg_name in query.argument_list]
-        with contextlib.closing(connection.cursor()) as cursor:
-            # Execute the query with the specified arguments
-            cursor.execute(sql, sql_args)
-            # Get and return the results
-            rows = cursor.fetchall()
-            columns = cursor.description
-            return rows, columns
-
-
-class DataReport(RepositoryItem):
-    """
-    Data reports are small snippets of xml that define
-    a limited django template.
-    """
-
-    repository = DataReportRepository()
-
-    def __init__(self, **kwargs):
-        self._html = None
-        self._data = kwargs
-
-    def __unicode__(self):
-        return self.title
-
-    def __repr__(self):
-        return "<DataReport name=%r>" % (self.name,)
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.report_detail", [self.name])
-
-    def _get_raw_html(self):
-        pathname = os.path.join(self.base_path, self.path)
-        try:
-            with open(pathname) as stream:
-                return stream.read()
-        except (IOError, OSError) as ex:
-            logging.error("Unable to load DataReport HTML file from %r: %s", pathname, ex)
-            return ""
-
-    def _get_html_template(self):
-        return Template(self._get_raw_html())
-
-    def _get_html_template_context(self):
-        return Context({
-            "API_URL": reverse("dashboard_app.views.dashboard_xml_rpc_handler"),
-            "STATIC_URL": settings.STATIC_URL
-        })
-
-    def get_html(self):
-        DEBUG = getattr(settings, "DEBUG", False)
-        if self._html is None or DEBUG is True:
-            template = self._get_html_template()
-            context = self._get_html_template_context()
-            self._html = template.render(context)
-        return self._html
-
-    @property
-    def title(self):
-        return self._data['title']
-
-    @property
-    def path(self):
-        return self._data['path']
-
-    @property
-    def name(self):
-        return self._data['name']
-
-    @property
-    def bug_report_url(self):
-        return self._data.get('bug_report_url')
-
-    @property
-    def author(self):
-        return self._data.get('author')
-
-    @property
-    def front_page(self):
-        return self._data['front_page']
-
-
-class Tag(models.Model):
-    """
-    Tag used for marking test runs.
-    """
-    name = models.SlugField(
-        verbose_name=_(u"Tag"),
-        max_length=256,
-        db_index=True,
-        unique=True)
-
-    def __unicode__(self):
-        return self.name
-
-
-class Image(models.Model):
-
-    name = models.SlugField(max_length=1024, unique=True)
-
-    filter = models.ForeignKey("TestRunFilter", related_name='+', null=True)
-
-    def __unicode__(self):
-        owner_name = getattr(self.filter, 'owner_name', '<NULL>')
-        return '%s, based on %s' % (self.name, owner_name)
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.images.image_report_detail", (), dict(name=self.name))
-
-
-class ImageSet(models.Model):
-
-    name = models.CharField(max_length=1024, unique=True)
-
-    images = models.ManyToManyField(Image)
-
-    def __unicode__(self):
-        return self.name
-
-
-class LaunchpadBug(models.Model):
-
-    bug_id = models.PositiveIntegerField(unique=True)
-
-    test_runs = models.ManyToManyField(TestRun, related_name='launchpad_bugs')
-
-    def __unicode__(self):
-        return unicode(self.bug_id)
-
-@receiver(post_delete)
-def file_cleanup(sender, instance, **kwargs):
-    """
-    Signal receiver used for remove FieldFile attachments when removing
-    objects (Bundle and Attachment) from the database.
-    """
-    if instance is None or sender not in (Bundle, Attachment):
-        return
-    meta = sender._meta
-
-    for field_name in meta.get_all_field_names():
-
-        # object that represents the metadata of the field
-        try:
-            field_meta = meta.get_field(field_name)
-        except FieldDoesNotExist:
-            continue
-
-        # we just want the FileField's, not all the fields
-        if not isinstance(field_meta, models.FileField):
-            continue
-
-        # the field itself is a FieldFile instance, proxied by FileField
-        field = getattr(instance, field_name)
-
-        # the 'path' attribute contains the name of the file we need
-        if hasattr(field, 'path') and os.path.exists(field.path):
-            field.storage.delete(field.path)
-
-
-class TestRunFilterAttribute(models.Model):
-
-    name = models.CharField(max_length=1024)
-    value = models.CharField(max_length=1024)
-
-    filter = models.ForeignKey("TestRunFilter", related_name="attributes")
-
-    def __unicode__(self):
-        return '%s = %s' % (self.name, self.value)
-
-
-class TestRunFilterTest(models.Model):
-
-    test = models.ForeignKey(Test, related_name="+")
-    filter = models.ForeignKey("TestRunFilter", related_name="tests")
-    index = models.PositiveIntegerField(
-        help_text = _(u"The index of this test in the filter"))
-
-    def __unicode__(self):
-        return unicode(self.test)
-
-
-class TestRunFilterTestCase(models.Model):
-
-    test_case = models.ForeignKey(TestCase, related_name="+")
-    test = models.ForeignKey(TestRunFilterTest, related_name="cases")
-    index = models.PositiveIntegerField(
-        help_text = _(u"The index of this case in the test"))
-
-    def __unicode__(self):
-        return unicode(self.test_case)
-
-
-class TestRunFilter(models.Model):
-
-    owner = models.ForeignKey(User)
-
-    name = models.SlugField(
-        max_length=1024,
-        help_text=("The <b>name</b> of a filter is used to refer to it in "
-                   "the web UI and in email notifications triggered by this "
-                   "filter."))
-
-    @property
-    def owner_name(self):
-        return '~%s/%s' % (self.owner.username, self.name)
-
-    class Meta:
-        unique_together = (('owner', 'name'))
-
-    bundle_streams = models.ManyToManyField(BundleStream)
-    bundle_streams.help_text = 'A filter only matches tests within the given <b>bundle streams</b>.'
-
-    public = models.BooleanField(
-        default=False, help_text="Whether other users can see this filter.")
-
-    build_number_attribute = models.CharField(
-        max_length=1024, blank=True, null=True,
-        help_text="For some filters, there is a natural <b>build number</b>.  If you specify the name of the attribute that contains the build number here, the results of the filter will be grouped and ordered by this build number.")
-
-    uploaded_by = models.ForeignKey(
-        User, null=True, blank=True, related_name='+',
-        help_text="Only consider bundles uploaded by this user")
-
-    def as_data(self):
-        tests = []
-        for trftest in self.tests.order_by('index').prefetch_related('cases'):
-            tests.append({
-                'test': trftest.test,
-                'test_cases': [trftestcase.test_case for trftestcase in trftest.cases.all().select_related('test_case')],
-                })
-        return {
-            'bundle_streams': self.bundle_streams.all(),
-            'attributes': self.attributes.all().values_list('name', 'value'),
-            'tests': tests,
-            'build_number_attribute': self.build_number_attribute,
-            'uploaded_by': self.uploaded_by,
-            }
-
-    def __unicode__(self):
-        return "<TestRunFilter ~%s/%s>" % (self.owner.username, self.name)
-
-    # given bundle:
-    # select from filter
-    #  where bundle.bundle_stream in filter.bundle_streams
-    #    and filter.test in (select test from bundle.test_runs)
-    #    and all the attributes on the filter are on a testrun in the bundle
-    #       = the minimum over testrun (the number of attributes on the filter that are not on the testrun) is 0
-    #    and (filter.test_case is null
-    #         or filter.test_case in select test_case from bundle.test_runs.test_results.test_cases)
-
-    @classmethod
-    def matches_against_bundle(self, bundle):
-        from dashboard_app.filters import FilterMatch
-        bundle_filters = bundle.bundle_stream.testrunfilter_set.all()
-        attribute_filters = bundle_filters.extra(
-            where=[
-            """(select min((select count(*)
-                              from dashboard_app_testrunfilterattribute
-                             where filter_id = dashboard_app_testrunfilter.id
-                               and (name, value) not in (select name, value
-                                                           from dashboard_app_namedattribute
-                                  where content_type_id = (
-                                          select django_content_type.id from django_content_type
-                                          where app_label = 'dashboard_app' and model='testrun')
-                                 and object_id = dashboard_app_testrun.id)))
-            from dashboard_app_testrun where dashboard_app_testrun.bundle_id = %s) = 0""" % bundle.id],
-            )
-        no_test_filters = list(attribute_filters.annotate(models.Count('tests')).filter(tests__count=0))
-        attribute_filters = list(attribute_filters)
-        no_test_case_filters = list(
-            TestRunFilter.objects.filter(
-                id__in=TestRunFilterTest.objects.filter(
-                    filter__in=attribute_filters, test__in=bundle.test_runs.all().values('test_id')).annotate(
-                    models.Count('cases')).filter(cases__count=0).values('filter__id'),
-                ))
-        tcf = TestRunFilter.objects.filter(
-            id__in=TestRunFilterTest.objects.filter(
-                filter__in=attribute_filters,
-                cases__test_case__id__in=bundle.test_runs.all().values('test_results__test_case__id')
-                ).values('filter__id')
-            )
-        test_case_filters = list(tcf)
-
-        filters = set(test_case_filters + no_test_case_filters + no_test_filters)
-        matches = []
-        bundle_with_counts = Bundle.objects.annotate(
-            pass_count=models.Sum('test_runs__denormalization__count_pass'),
-            unknown_count=models.Sum('test_runs__denormalization__count_unknown'),
-            skip_count=models.Sum('test_runs__denormalization__count_skip'),
-            fail_count=models.Sum('test_runs__denormalization__count_fail')).get(
-            id=bundle.id)
-        for filter in filters:
-            match = FilterMatch()
-            match.filter = filter
-            match.filter_data = filter.as_data()
-            match.test_runs = list(bundle.test_runs.all())
-            match.specific_results = list(
-                TestResult.objects.filter(
-                    test_case__id__in=filter.tests.all().values('cases__test_case__id'),
-                    test_run__bundle=bundle))
-            b = bundle_with_counts
-            match.result_count = b.unknown_count + b.skip_count + b.pass_count + b.fail_count
-            match.pass_count = bundle_with_counts.pass_count
-            matches.append(match)
-        return matches
-
-    @models.permalink
-    def get_absolute_url(self):
-        return (
-            "dashboard_app.views.filters.views.filter_detail",
-            [self.owner.username, self.name])
-
-
-class TestRunFilterSubscription(models.Model):
-
-    user = models.ForeignKey(User)
-
-    filter = models.ForeignKey(TestRunFilter)
-
-    class Meta:
-        unique_together = (('user', 'filter'))
-
-    NOTIFICATION_FAILURE, NOTIFICATION_ALWAYS = range(2)
-
-    NOTIFICATION_CHOICES = (
-        (NOTIFICATION_FAILURE, "Only when failed"),
-        (NOTIFICATION_ALWAYS, "Always"))
-
-    level = models.IntegerField(
-        default=NOTIFICATION_FAILURE, choices=NOTIFICATION_CHOICES,
-        help_text=("You can choose to be <b>notified by email</b>:<ul><li>whenever a test "
-                   "that matches the criteria of this filter is executed"
-                   "</li><li>only when a test that matches the criteria of this filter fails</ul>"))
-
-    @classmethod
-    def recipients_for_bundle(cls, bundle):
-        matches = TestRunFilter.matches_against_bundle(bundle)
-        matches_by_filter_id = {}
-        for match in matches:
-            matches_by_filter_id[match.filter.id] = match
-        args = [models.Q(filter_id__in=list(matches_by_filter_id))]
-        bs = bundle.bundle_stream
-        if not bs.is_public:
-            if bs.group:
-                args.append(models.Q(user__in=bs.group.user_set.all()))
-            else:
-                args.append(models.Q(user=bs.user))
-        subscriptions = TestRunFilterSubscription.objects.filter(*args)
-        recipients = {}
-        for sub in subscriptions:
-            match = matches_by_filter_id[sub.filter.id]
-            if sub.level == cls.NOTIFICATION_FAILURE:
-                failure_found = False
-                if not match.filter_data['tests']:
-                    failure_found = match.pass_count != match.result_count
-                else:
-                    for t in match.filter_data['tests']:
-                        if not t['test_cases']:
-                            for tr in match.test_runs:
-                                if tr.test == t.test:
-                                    if tr.denormalization.count_pass != tr.denormalization.count_all():
-                                        failure_found = True
-                                        break
-                        if failure_found:
-                            break
-                if not failure_found:
-                    for r in match.specific_results:
-                        if r.result != TestResult.RESULT_PASS:
-                            failure_found = True
-                            break
-                if not failure_found:
-                    continue
-            recipients.setdefault(sub.user, []).append(match)
-        return recipients
-
-
-def send_bundle_notifications(sender, bundle, **kwargs):
-    try:
-        recipients = TestRunFilterSubscription.recipients_for_bundle(bundle)
-        domain = '???'
-        try:
-            site = Site.objects.get_current()
-        except (Site.DoesNotExist, ImproperlyConfigured):
-            pass
-        else:
-            domain = site.domain
-        url_prefix = 'http://%s' % domain
-        for user, matches in recipients.items():
-            logging.info("sending bundle notification to %s", user)
-            data = {'bundle': bundle, 'user': user, 'matches': matches, 'url_prefix': url_prefix}
-            mail = render_to_string(
-                'dashboard_app/filter_subscription_mail.txt',
-                data)
-            filter_names = ', '.join(match.filter.name for match in matches)
-            send_mail(
-                "LAVA result notification: " + filter_names, mail,
-                settings.SERVER_EMAIL, [user.email])
-    except:
-        logging.exception("send_bundle_notifications failed")
-        raise
-
-
-bundle_was_deserialized.connect(send_bundle_notifications)
-
-
-class PMQABundleStream(models.Model):
-
-    bundle_stream = models.ForeignKey(BundleStream, related_name='+')
-
-
-class ImageReport(models.Model):
-
-    name = models.SlugField(max_length=1024, unique=True)
-
-    description = models.TextField(blank=True, null=True)
-
-    is_published = models.BooleanField(
-        default=False,
-        verbose_name='Published')
-
-    def __unicode__(self):
-        return self.name
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.image_reports.views.image_report_detail",
-                (), dict(name=self.name))
-
-# Chart types
-CHART_TYPES = ((r'pass/fail', 'Pass/Fail'),
-               (r'measurement', 'Measurement'))
-# Chart representation
-REPRESENTATION_TYPES = ((r'lines', 'Lines'),
-                        (r'bars', 'Bars'))
-
-
-class ImageReportChart(models.Model):
-
-    name = models.CharField(max_length=100)
-
-    description = models.TextField(blank=True, null=True)
-
-    image_report = models.ForeignKey(
-        ImageReport,
-        default=None,
-        null=False,
-        on_delete=models.CASCADE)
-
-    chart_type = models.CharField(
-        max_length=20,
-        choices=CHART_TYPES,
-        verbose_name='Chart type',
-        blank=False,
-        default="pass/fail",
-        )
-
-    target_goal = models.DecimalField(
-        blank = True,
-        decimal_places = 5,
-        max_digits = 10,
-        null = True,
-        verbose_name = 'Target goal')
-
-    is_interactive = models.BooleanField(
-        default=False,
-        verbose_name='Chart is interactive')
-
-    is_data_table_visible = models.BooleanField(
-        default=False,
-        verbose_name='Data table is visible')
-
-    def __unicode__(self):
-        return self.name
-
-    @models.permalink
-    def get_absolute_url(self):
-        return ("dashboard_app.views.image_reports.views.image_chart_detail",
-                (), dict(id=self.id))
-
-
-class ImageChartFilter(models.Model):
-
-    image_chart = models.ForeignKey(
-        ImageReportChart,
-        null=False,
-        on_delete=models.CASCADE)
-
-    filter = models.ForeignKey(
-        TestRunFilter,
-        null=True,
-        on_delete=models.SET_NULL)
-
-    representation = models.CharField(
-        max_length=20,
-        choices=REPRESENTATION_TYPES,
-        verbose_name='Representation',
-        blank=False,
-        default="lines",
-        )
-
-    @models.permalink
-    def get_absolute_url(self):
-        return (
-            "dashboard_app.views.image_reports.views.image_chart_filter_edit",
-            (), dict(id=self.id))
-
-
-class ImageChartTest(models.Model):
-
-    class Meta:
-        unique_together = ("image_chart_filter", "test")
-
-    image_chart_filter = models.ForeignKey(
-        ImageChartFilter,
-        null=False,
-        on_delete=models.CASCADE)
-
-    test = models.ForeignKey(
-        Test,
-        null=False,
-        on_delete=models.CASCADE)
-
-    name = models.CharField(max_length=200)
-
-
-class ImageChartTestCase(models.Model):
-
-    class Meta:
-        unique_together = ("image_chart_filter", "test_case")
-
-    image_chart_filter = models.ForeignKey(
-        ImageChartFilter,
-        null=False,
-        on_delete=models.CASCADE)
-
-    test_case = models.ForeignKey(
-        TestCase,
-        null=False,
-        on_delete=models.CASCADE)
-
-    name = models.CharField(max_length=200)
-

=== removed file 'dashboard_app/patches.py'
--- dashboard_app/patches.py	2011-07-09 15:08:42 +0000
+++ dashboard_app/patches.py	1970-01-01 00:00:00 +0000
@@ -1,112 +0,0 @@
-"""
-Patches for django bugs that affect this package
-"""
-
-class PatchDjangoTicket1476(object):
-    """
-    Patch for bug http://code.djangoproject.com/ticket/1476
-    """
-
-    @classmethod
-    def apply_if_needed(patch):
-        import django
-        if django.VERSION[0:3] <= (1, 2, 4):
-            patch.apply()
-
-    @classmethod
-    def apply(patch):
-        from django.utils.decorators import method_decorator
-        from django.views.decorators.csrf import csrf_protect
-
-        @method_decorator(csrf_protect)
-        def __call__(self, request, *args, **kwargs):
-            """
-            Main method that does all the hard work, conforming to the Django view
-            interface.
-            """
-            if 'extra_context' in kwargs:
-                self.extra_context.update(kwargs['extra_context'])
-            current_step = self.determine_step(request, *args, **kwargs)
-            self.parse_params(request, *args, **kwargs)
-
-            # Sanity check.
-            if current_step >= self.num_steps():
-                raise Http404('Step %s does not exist' % current_step)
-
-            # Process the current step. If it's valid, go to the next step or call
-            # done(), depending on whether any steps remain.
-            if request.method == 'POST':
-                form = self.get_form(current_step, request.POST)
-            else:
-                form = self.get_form(current_step)
-
-            if form.is_valid():
-                # Validate all the forms. If any of them fail validation, that
-                # must mean the validator relied on some other input, such as
-                # an external Web site.
-
-                # It is also possible that validation might fail under certain
-                # attack situations: an attacker might be able to bypass previous
-                # stages, and generate correct security hashes for all the
-                # skipped stages by virtue of:
-                #  1) having filled out an identical form which doesn't have the
-                #     validation (and does something different at the end),
-                #  2) or having filled out a previous version of the same form
-                #     which had some validation missing,
-                #  3) or previously having filled out the form when they had
-                #     more privileges than they do now.
-                #
-                # Since the hashes only take into account values, and not other
-                # other validation the form might do, we must re-do validation
-                # now for security reasons.
-                previous_form_list = [self.get_form(i, request.POST) for i in range(current_step)]
-
-                for i, f in enumerate(previous_form_list):
-                    if request.POST.get("hash_%d" % i, '') != self.security_hash(request, f):
-                        return self.render_hash_failure(request, i)
-
-                    if not f.is_valid():
-                        return self.render_revalidation_failure(request, i, f)
-                    else:
-                        self.process_step(request, f, i)
-
-                # Now progress to processing this step:
-                self.process_step(request, form, current_step)
-                next_step = current_step + 1
-
-
-                if next_step == self.num_steps():
-                    return self.done(request, previous_form_list + [form])
-                else:
-                    form = self.get_form(next_step)
-                    self.step = current_step = next_step
-
-            return self.render(form, request, current_step)
-
-        from django.contrib.formtools.wizard import FormWizard
-        FormWizard.__call__ = __call__
-
-
-class PatchDjangoTicket15155(object):
-    """
-    Patch for bug http://code.djangoproject.com/ticket/15155
-    """
-
-    PROPER_FORMAT = r'(?<!%)%s'
-
-    @classmethod
-    def apply_if_needed(patch):
-        from django.db.backends.sqlite3 import base
-        if base.FORMAT_QMARK_REGEX != patch.PROPER_FORMAT:
-            patch.apply()
-
-    @classmethod
-    def apply(cls):
-        from django.db.backends.sqlite3 import base
-        import re
-        base.FORMAT_QMARK_REGEX = re.compile(cls.PROPER_FORMAT)
-
-
-def patch():
-    PatchDjangoTicket1476.apply_if_needed()
-    PatchDjangoTicket15155.apply_if_needed()

=== removed directory 'dashboard_app/repositories'
=== removed file 'dashboard_app/repositories/__init__.py'
--- dashboard_app/repositories/__init__.py	2011-10-13 11:55:18 +0000
+++ dashboard_app/repositories/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,230 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from __future__ import with_statement
-
-import abc
-import logging
-import os
-import thread
-
-from django.conf import settings
-
-
-class RepositoryItemMeta(abc.ABCMeta):
-    """
-    Meta class for RepositoryItem
-
-    Adds magic to set repository._item_cls to the non-meta
-    class object that use this meta-class.
-    """
-
-    def __new__(mcls, name, bases, namespace):
-        cls = super(RepositoryItemMeta, mcls).__new__(
-            mcls, name, bases, namespace)
-        if "repository" in namespace:
-            repo = cls.repository
-            repo.item_cls = cls
-        return cls
-
-
-class RepositoryItem(object):
-    """
-    Repository Item, element of a Repository.
-
-    Each repository item is loaded from a XML file.
-    """
-
-    __metaclass__ = RepositoryItemMeta
-
-    _base_path = None
-
-    def _load_from_external_representation(self, pathname):
-        self._base_path = os.path.dirname(pathname)
-
-    @property
-    def base_path(self):
-        return self._base_path
-
-    class DoesNotExist(Exception):
-        pass
-
-    class MultipleValuesReturned(Exception):
-        pass
-
-
-class RepositoryQuerySet(object):
-    """
-    QuerySet-like class for poking at RepositoryItems
-    """
-
-    def __iter__(self):
-        return iter(self._items)
-
-    def __len__(self):
-        return len(self._items)
-
-    def __nonzero__(self):
-        return len(self._items) != 0
-
-    def __getitem__(self, slice_or_index):
-        return self._items.__getitem__(slice_or_index)
-
-# Django QuerySet like API:
-
-    def count(self):
-        return len(self)
-
-    def all(self):
-        return self
-
-    def get(self, **kwargs):
-        query = self.filter(**kwargs)
-        if len(query) == 1:
-            return query[0]
-        if not query:
-            raise self.model.DoesNotExist()
-        else:
-            raise self.model.MultipleValuesReturned()
-
-    def filter(self, **kwargs):
-        return self._sub_query([
-            item for item in self._items
-            if all(
-                (getattr(item, attr) == value)
-                for attr, value in kwargs.iteritems())])
-
-# Internal API
-
-    def __init__(self, model, items):
-        self.model = model
-        self._items = items
-
-    def _sub_query(self, items):
-        return self.__class__(self.model, items)
-
-
-class Repository(object):
-    """
-    Repository
-
-    A container of XML documents loaded from disk that behave somewhat like
-    django-built in database ORM
-    """
-
-    __metaclass__ = abc.ABCMeta
-
-    loader_lock = thread.allocate_lock()
-
-    def __init__(self):
-        self.item_cls = None  # later patched by RepositoryItemMeta
-        self._items = []
-        self._did_load = False
-
-    def _queryset(self):
-        # HOT FIX: use a lock while loading the stuff from disk
-        with self.loader_lock:
-            # In development mode always reload repository items
-            if getattr(settings, "DEBUG", False) is True:
-                self._did_load = False
-            if not self._did_load:
-                self._items = []
-                self._load_default()
-                self._did_load = True
-        return RepositoryQuerySet(self.item_cls, self._items)
-
-    def all(self):
-        return self._queryset().all()
-
-    def filter(self, **kwargs):
-        return self._queryset().filter(**kwargs)
-
-    def get(self, **kwargs):
-        return self._queryset().get(**kwargs)
-
-    def load_from_directory(self, directory):
-        try:
-            items = os.listdir(directory)
-        except (OSError, IOError) as exc:
-            logging.exception("Unable to enumreate directory: %s: %s",
-                              directory, exc)
-        else:
-            for name in items:
-                pathname = os.path.join(directory, name)
-                if os.path.isfile(pathname) and pathname.endswith(".xml"):
-                    self.load_from_file(pathname)
-
-    @abc.abstractmethod
-    def load_from_xml_string(self, text):
-        """
-        Load an IRepositoryItem from specified XML text
-        """
-
-    def load_from_file(self, pathname):
-        try:
-            with open(pathname, "rt") as stream:
-                text = stream.read()
-            item = self.load_from_xml_string(text)
-            # Let the item know where it came from
-            item._load_from_external_representation(pathname)
-            self._items.append(item)
-        except Exception as exc:
-            logging.exception("Unable to load object into repository %s: %s",
-                              pathname, exc)
-
-    @abc.abstractproperty
-    def settings_variable(self):
-        """
-        VARIABLE to look for in django settings. It should
-        contain a list of directories to look for .xml
-        files.
-        """
-
-    def _load_default(self):
-        from django.conf import settings
-        for dirname in getattr(settings, self.settings_variable, []):
-            self.load_from_directory(dirname)
-
-
-class Undefined(object):
-    """
-    Undefined object, as in JavaScript.
-
-    Similar to None but serves different purpose. While None is often "empty"
-    Undefined literally means "not set", this allows to use None as a normal
-    (non-special cased value).
-    """
-    def __repr__(self):
-        return "undefined"
-
-# Undefined object singleton
-Undefined = Undefined()
-
-
-class Object(object):
-    """
-    Object, as in JavaScript.
-
-    The only noticeable difference from plain python object is that undefined
-    attributes do not raise AttributeError and instead produce Undefined
-    values.
-    """
-
-    def __getattr__(self, name):
-        return Undefined

=== removed file 'dashboard_app/repositories/common.py'
--- dashboard_app/repositories/common.py	2011-07-22 00:05:03 +0000
+++ dashboard_app/repositories/common.py	1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from xml.sax.handler import ContentHandler
-import re
-
-
-class BaseContentHandler(ContentHandler):
-
-    def _end_text(self):
-        """
-        Stop collecting text and produce a stripped string with de-duplicated
-        whitespace
-        """
-        full_text = re.sub("\s+", " ", u''.join(self._text)).strip()
-        self.text = None
-        return full_text
-        
-    def _start_text(self):
-        """
-        Start collecting text
-        """
-        self._text = []
-            
-    def characters(self, content):
-        if isinstance(self._text, list):
-            self._text.append(content)
-
-    def startDocument(self):
-        # Text can be None or a [] that accumulates all detected text
-        self._text = None

=== removed file 'dashboard_app/repositories/data_report.py'
--- dashboard_app/repositories/data_report.py	2011-10-13 11:55:44 +0000
+++ dashboard_app/repositories/data_report.py	1970-01-01 00:00:00 +0000
@@ -1,79 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from xml.sax import parseString
-
-from dashboard_app.repositories import Repository, Undefined, Object
-from dashboard_app.repositories.common import BaseContentHandler
-
-
-class _DataReportHandler(BaseContentHandler):
-    """
-    ContentHandler subclass for parsing DataReport documents
-    """
-    
-    def startDocument(self):
-        # Classic-classes 
-        BaseContentHandler.startDocument(self)
-        # Data report object
-        self.obj = Object()
-
-    def endDocument(self):
-        if self.obj.name is Undefined:
-            raise ValueError("No data view definition found")
-        if self.obj.title is Undefined:
-            raise ValueError("Data report without a title")
-        if self.obj.path is Undefined:
-            raise ValueError("Data report without a path")
-
-    def startElement(self, name, attrs):
-        if name == "data-report":
-            if "name" not in attrs:
-                raise ValueError("Data report without a name")
-            self.obj.name = attrs["name"]
-            self.obj.front_page = attrs.get('front_page') == "yes"
-        elif name == "title" or name == "path":
-            self._start_text()
-                
-    def endElement(self, name):
-        if name == "title":
-            self.obj.title = self._end_text()
-        elif name == "path":
-            self.obj.path = self._end_text()
-
-
-class DataReportRepository(Repository):
-
-    @property
-    def settings_variable(self):
-        return "DATAREPORT_DIRS"
-
-    def load_from_xml_string(self, text):
-        handler = _DataReportHandler()
-        parseString(text, handler)
-        return self.item_cls(
-            name=handler.obj.name,
-            title=handler.obj.title,
-            path=handler.obj.path,
-            front_page=handler.obj.front_page)
-
-
-__all__ = [
-    "DataReportRepository",
-]

=== removed file 'dashboard_app/repositories/data_view.py'
--- dashboard_app/repositories/data_view.py	2011-07-22 00:11:36 +0000
+++ dashboard_app/repositories/data_view.py	1970-01-01 00:00:00 +0000
@@ -1,133 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-DataViews: Encapsulated SQL query definitions.
-
-Implementation of the following launchpad blueprint:
-https://blueprints.launchpad.net/launch-control/+spec/other-linaro-n-data-views-for-launch-control
-"""
-
-
-from xml.sax import parseString
-
-from dashboard_app.repositories import Repository, Undefined, Object
-from dashboard_app.repositories.common import BaseContentHandler
-
-
-class _DataViewHandler(BaseContentHandler):
-
-    """
-    ContentHandler subclass for parsing DataView documents
-    """
-    
-    def startDocument(self):
-        # Classic-classes 
-        BaseContentHandler.startDocument(self)
-        # Data view object
-        self.obj = Object()
-        # Set default values
-        self.obj.name = Undefined
-        self.obj.backend_queries = {}
-        self.obj.arguments = []
-        self.obj.documentation = None
-        self.obj.summary = None
-        # Internal variables
-        self._current_backend_query = None
-
-    def endDocument(self):
-        # TODO: check if we have anything defined
-        if self.obj.name is Undefined:
-            raise ValueError("No data view definition found")
-
-    def startElement(self, name, attrs):
-        if name == "data-view":
-            self.obj.name = attrs["name"]
-        elif name == "summary" or name == "documentation":
-            self._start_text()
-        elif name == "sql":
-            self._start_text()
-            self._current_backend_query = BackendSpecificQuery(
-                attrs.get("backend"), None, [])
-            self.obj.backend_queries[
-                self._current_backend_query.backend] = self._current_backend_query
-        elif name == "value":
-            if "name" not in attrs:
-                raise ValueError("<value> requires attribute 'name'")
-            self._text.append("{" + attrs["name"] + "}")
-            self._current_backend_query.argument_list.append(attrs["name"])
-        elif name == "argument":
-            if "name" not in attrs:
-                raise ValueError("<argument> requires attribute 'name'")
-            if "type" not in attrs:
-                raise ValueError("<argument> requires attribute 'type'")
-            if attrs["type"] not in ("string", "number", "boolean", "timestamp"):
-                raise ValueError("invalid value for argument 'type' on <argument>")
-            argument = Argument(name=attrs["name"], type=attrs["type"],
-                                   default=attrs.get("default", None),
-                                   help=attrs.get("help", None))
-            self.obj.arguments.append(argument)
-                
-    def endElement(self, name):
-        if name == "sql":
-            self._current_backend_query.sql_template = self._end_text()
-            self._current_backend_query = None
-        elif name == "documentation":
-            self.obj.documentation = self._end_text()
-        elif name == "summary":
-            self.obj.summary = self._end_text()
-
-
-class Argument(object):
-    """
-    Data view argument for SQL prepared statements
-    """
-
-    def __init__(self, name, type, default, help):
-        self.name = name
-        self.type = type
-        self.default = default
-        self.help = help 
-
-
-class BackendSpecificQuery(object):
-    """
-    Backend-specific query and argument list
-    """
-
-    def __init__(self, backend, sql_template, argument_list):
-        self.backend = backend
-        self.sql_template = sql_template
-        self.argument_list = argument_list
-
-
-class DataViewRepository(Repository):
-
-    @property
-    def settings_variable(self):
-        return "DATAVIEW_DIRS"
-
-    def load_from_xml_string(self, text):
-        handler = _DataViewHandler()
-        parseString(text, handler)
-        return self.item_cls(**handler.obj.__dict__)
-
-
-__all__ = [
-    "DataViewRepository",
-]

=== removed file 'dashboard_app/signals.py'
--- dashboard_app/signals.py	2011-09-27 13:13:53 +0000
+++ dashboard_app/signals.py	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-# Copyright (C) 2010, 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.dispatch import Signal
-
-bundle_was_deserialized = Signal(providing_args=['bundle'])

=== removed directory 'dashboard_app/static'
=== removed directory 'dashboard_app/static/dashboard_app'
=== removed directory 'dashboard_app/static/dashboard_app/css'
=== removed file 'dashboard_app/static/dashboard_app/css/dashboard.css'
--- dashboard_app/static/dashboard_app/css/dashboard.css	2012-12-09 23:45:07 +0000
+++ dashboard_app/static/dashboard_app/css/dashboard.css	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-.lava-chart {
-  width: 600px;
-  height: 250px;
-  margin: 1em auto;
-  padding: 1em;
-}
-
-ul.attachments {
-    padding-left: 10px;
-}
-ul.attachments li {
-    background: url("../images/file-icon.png") no-repeat;
-    list-style-type: none;
-    padding-left: 20px;
-}
-
-#lava-sidebar ul.attributes li {
-    padding-left: 0;
-    background: none;
-    list-style-type: none;
-}

=== removed file 'dashboard_app/static/dashboard_app/css/filter-detail.css'
--- dashboard_app/static/dashboard_app/css/filter-detail.css	2013-01-10 20:37:00 +0000
+++ dashboard_app/static/dashboard_app/css/filter-detail.css	1970-01-01 00:00:00 +0000
@@ -1,52 +0,0 @@
-table.select-compare1 td { cursor: pointer; }
-table.select-compare1 tr.even td {
-    background-color: #ccf;
-}
-table.select-compare1 tr.even.hover td {
-    background-color: #77f;
-}
-table.select-compare1 tr.odd td {
-    background-color: #aaf;
-}
-table.select-compare1 tr.odd.hover td {
-    background-color: #77f;
-}
-
-table.select-compare2 td { cursor: pointer; }
-table.select-compare2 tr.even td {
-    background-color: #fcc;
-}
-table.select-compare2 tr.odd td {
-    background-color: #faa;
-}
-table.select-compare2 tr.selected-1 td {
-    background-color: #77f;
-}
-table.select-compare2 tr.selected-1.hover td {
-    background-color: #77f;
-}
-table.select-compare2 tr.hover td {
-    background-color: #f77;
-}
-table.select-compare3 tr.selected-1 td {
-    background-color: #77f;
-}
-table.select-compare3 tr.selected-1.hover td {
-    background-color: #77f;
-}
-table.select-compare3 tr.selected-2 td {
-    background-color: #f77;
-}
-table.select-compare3 tr.selected-2.hover td {
-    background-color: #f77;
-}
-table.select-compare3 tr.selected-1 {
-    cursor: pointer;
-}
-table.select-compare3 tr.selected-2 {
-    cursor: pointer;
-}
-#filter-table input {
-    margin-top: 0;
-    margin-bottom: 0;
-}
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/css/filter-edit.css'
--- dashboard_app/static/dashboard_app/css/filter-edit.css	2012-09-13 03:16:48 +0000
+++ dashboard_app/static/dashboard_app/css/filter-edit.css	1970-01-01 00:00:00 +0000
@@ -1,20 +0,0 @@
-@import url("../../admin/css/widgets.css");
-div.selector span.helptext { display: none; }
-div.selector h2 { margin: 0; font-size: 11pt; }
-div.selector a { text-decoration: none; }
-div.selector select { height: 10em; }
-div.selector ul.selector-chooser { margin-top: 5.5em; }
-div.selector .selector-chosen select {
-  border: 1px solid rgb(204, 204, 204);
-  border-top: none;
-}
-td.test-cell {
-  vertical-align: top;
-}
-table.test-case-formset {
-  border-collapse: collapse;
-}
-table.test-case-formset td {
-  padding-top: 0;
-  padding-bottom: 0;
-}
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/css/image-charts.css'
--- dashboard_app/static/dashboard_app/css/image-charts.css	2013-09-12 14:12:07 +0000
+++ dashboard_app/static/dashboard_app/css/image-charts.css	1970-01-01 00:00:00 +0000
@@ -1,82 +0,0 @@
-@import url("../../admin/css/widgets.css");
-
-div.selector { clear: both; }
-div.selector span.helptext { display: none; }
-div.selector h2 { margin: 0; font-size: 11pt; }
-div.selector a { text-decoration: none; }
-div.selector select { height: 10em; }
-div.selector ul.selector-chooser { margin-top: 5.5em; }
-div.selector .selector-chosen select {
-  border: 1px solid rgb(204, 204, 204);
-  border-top: none;
-}
-
-.list-container {
-    border: 1px solid #000000;
-    clear: both;
-    margin: 10px 10px 10px 10px;
-    padding: 10px;
-    width: 50%;
-}
-
-.form-field {
-    margin-bottom: 5px;
-    vertical-align: top;
-}
-
-.form-field label {
-    vertical-align: top;
-    width: 100px;
-    display: inline-block;
-    margin-left: 10px;
-}
-
-.submit-button {
-    margin-top: 20px;
-    margin-left: 10px;
-}
-
-.filter-headline {
-    font-weight: bold;
-    font-size: 16px;
-}
-
-.filter-container {
-    margin-bottom: 10px;
-    clear: both;
-}
-
-.filter-title {
-    font-weight: bold;
-    font-size: 15px;
-    margin-bottom: 10px;
-}
-
-.chart-title {
-    font-weight: bold;
-    font-size: 15px;
-    margin-bottom: 10px;
-}
-
-.errors {
-    color: red;
-}
-
-.fields-container {
-    margin-left: 10px;
-}
-
-#filters_div {
-    margin: 10px 0 0 10px;
-    border: 1px solid #000000;
-    clear: both;
-    width: 75%;
-    padding: 5px 0 10px 10px;
-    overflow: auto;
-}
-
-#alias_container {
-    font-weight: bold;
-    float: left;
-    display: none;
-}
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/css/image-report.css'
--- dashboard_app/static/dashboard_app/css/image-report.css	2013-06-18 13:12:18 +0000
+++ dashboard_app/static/dashboard_app/css/image-report.css	1970-01-01 00:00:00 +0000
@@ -1,96 +0,0 @@
-#outer-table, .inner-table {
-    border-collapse: collapse;
-}
-#outer-table > tbody > tr > td {
-    padding: 0;
-    vertical-align: top;
-}
-#outer-table th {
-    text-align: left;
-}
-.inner-table td, .inner-table th {
-    min-width: 105px;
-    padding: 3px 4px;
-    border: thin solid black;
-}
-.inner-table td.present a {
-    color: #00a;
-    text-decoration: none;
-}
-.inner-table td.present a:hover {
-    text-decoration: underline;
-}
-.inner-table td.pass {
-    background-color: #4e4;
-}
-.inner-table td.fail {
-    background-color: #e44;
-}
-.inner-table td.missing {
-    background-color: #bbb;
-}
-#scroller {
-    width: 800px;
-    overflow-x: scroll;
-    overflow-y: visible;
-}
-#scroller td:first-child, #scroller th:first-child {
-    border-left: none;
-}
-.bug-links {
-    float: right;
-}
-#go-to-bug-dialog {
-    text-align: center;
-}
-#inner-container {
-    width: 80%;
-    height:250px;
-    margin:0 auto;
-    margin-left: 10px;
-    float: left;
-}
-#legend-container {
-    float: left;
-    margin-left: 20px;
-}
-#build_numbers_filter {
-    margin: 5px 0 0 20px;
-}
-#outer-container {
-    overflow: auto;
-}
-#toggle-graph-container {
-    margin-top: 5px;
-}
-#filters {
-    border: 1px solid #000000;
-    clear: both;
-    margin: 20px 2px 20px 0px;
-}
-#tests_filter, #graph_type_filter, #target_goal_filter {
-    margin: 5px 0 10px 20px;
-}
-#filter_headline {
-    font-weight: bold;
-    font-size: 16px;
-    margin: 5px 0 0 10px;
-}
-#filter_headline a {
-    font-weight: normal;
-    font-size: 12px;
-}
-#test_headline, #build_number_headline, #graph_type_headline, #target_goal_headline {
-    width: 120px;
-    float: left;
-}
-#tooltip {
-    position: absolute;
-    z-index: 3000;
-    border: 1px solid #111;
-    background-color: #eee;
-    color: #000;
-    padding: 5px;
-    opacity: 0.85;
-}
-#tooltip h3, #tooltip div { margin: 0; }

=== removed file 'dashboard_app/static/dashboard_app/css/pygments.css'
--- dashboard_app/static/dashboard_app/css/pygments.css	2011-05-03 18:20:24 +0000
+++ dashboard_app/static/dashboard_app/css/pygments.css	1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
-.pygments .hll { background-color: #ffffcc }
-.pygments .c { color: #60a0b0; font-style: italic } /* Comment */
-.pygments .err { border: 1px solid #FF0000 } /* Error */
-.pygments .k { color: #007020; font-weight: bold } /* Keyword */
-.pygments .o { color: #666666 } /* Operator */
-.pygments .cm { color: #60a0b0; font-style: italic } /* Comment.Multiline */
-.pygments .cp { color: #007020 } /* Comment.Preproc */
-.pygments .c1 { color: #60a0b0; font-style: italic } /* Comment.Single */
-.pygments .cs { color: #60a0b0; background-color: #fff0f0 } /* Comment.Special */
-.pygments .gd { color: #A00000 } /* Generic.Deleted */
-.pygments .ge { font-style: italic } /* Generic.Emph */
-.pygments .gr { color: #FF0000 } /* Generic.Error */
-.pygments .gh { color: #000080; font-weight: bold } /* Generic.Heading */
-.pygments .gi { color: #00A000 } /* Generic.Inserted */
-.pygments .go { color: #808080 } /* Generic.Output */
-.pygments .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
-.pygments .gs { font-weight: bold } /* Generic.Strong */
-.pygments .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
-.pygments .gt { color: #0040D0 } /* Generic.Traceback */
-.pygments .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
-.pygments .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
-.pygments .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
-.pygments .kp { color: #007020 } /* Keyword.Pseudo */
-.pygments .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
-.pygments .kt { color: #902000 } /* Keyword.Type */
-.pygments .m { color: #40a070 } /* Literal.Number */
-.pygments .s { color: #4070a0 } /* Literal.String */
-.pygments .na { color: #4070a0 } /* Name.Attribute */
-.pygments .nb { color: #007020 } /* Name.Builtin */
-.pygments .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
-.pygments .no { color: #60add5 } /* Name.Constant */
-.pygments .nd { color: #555555; font-weight: bold } /* Name.Decorator */
-.pygments .ni { color: #d55537; font-weight: bold } /* Name.Entity */
-.pygments .ne { color: #007020 } /* Name.Exception */
-.pygments .nf { color: #06287e } /* Name.Function */
-.pygments .nl { color: #002070; font-weight: bold } /* Name.Label */
-.pygments .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
-.pygments .nt { color: #062873; font-weight: bold } /* Name.Tag */
-.pygments .nv { color: #bb60d5 } /* Name.Variable */
-.pygments .ow { color: #007020; font-weight: bold } /* Operator.Word */
-.pygments .w { color: #bbbbbb } /* Text.Whitespace */
-.pygments .mf { color: #40a070 } /* Literal.Number.Float */
-.pygments .mh { color: #40a070 } /* Literal.Number.Hex */
-.pygments .mi { color: #40a070 } /* Literal.Number.Integer */
-.pygments .mo { color: #40a070 } /* Literal.Number.Oct */
-.pygments .sb { color: #4070a0 } /* Literal.String.Backtick */
-.pygments .sc { color: #4070a0 } /* Literal.String.Char */
-.pygments .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
-.pygments .s2 { color: #4070a0 } /* Literal.String.Double */
-.pygments .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
-.pygments .sh { color: #4070a0 } /* Literal.String.Heredoc */
-.pygments .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
-.pygments .sx { color: #c65d09 } /* Literal.String.Other */
-.pygments .sr { color: #235388 } /* Literal.String.Regex */
-.pygments .s1 { color: #4070a0 } /* Literal.String.Single */
-.pygments .ss { color: #517918 } /* Literal.String.Symbol */
-.pygments .bp { color: #007020 } /* Name.Builtin.Pseudo */
-.pygments .vc { color: #bb60d5 } /* Name.Variable.Class */
-.pygments .vg { color: #bb60d5 } /* Name.Variable.Global */
-.pygments .vi { color: #bb60d5 } /* Name.Variable.Instance */
-.pygments .il { color: #40a070 } /* Literal.Number.Integer.Long */

=== removed file 'dashboard_app/static/dashboard_app/css/wider-filter-horizontal.css'
--- dashboard_app/static/dashboard_app/css/wider-filter-horizontal.css	2012-09-25 22:38:13 +0000
+++ dashboard_app/static/dashboard_app/css/wider-filter-horizontal.css	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-.selector {
-    width: 1000px;
-    float: left;
-}
-
-.selector select {
-    width: 480px;
-    height: 17.2em;
-}
-
-.selector-available, .selector-chosen {
-    float: left;
-    width: 480px;
-    text-align: center;
-    margin-bottom: 5px;
-}

=== removed directory 'dashboard_app/static/dashboard_app/images'
=== removed file 'dashboard_app/static/dashboard_app/images/ajax-progress.gif'
Binary files dashboard_app/static/dashboard_app/images/ajax-progress.gif	2013-09-09 11:47:00 +0000 and dashboard_app/static/dashboard_app/images/ajax-progress.gif	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/attachment.png'
Binary files dashboard_app/static/dashboard_app/images/attachment.png	2012-12-09 22:20:28 +0000 and dashboard_app/static/dashboard_app/images/attachment.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/details_close.png'
Binary files dashboard_app/static/dashboard_app/images/details_close.png	2011-07-08 04:20:37 +0000 and dashboard_app/static/dashboard_app/images/details_close.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/details_open.png'
Binary files dashboard_app/static/dashboard_app/images/details_open.png	2011-07-08 04:20:37 +0000 and dashboard_app/static/dashboard_app/images/details_open.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/file-icon.png'
Binary files dashboard_app/static/dashboard_app/images/file-icon.png	2012-12-07 03:09:21 +0000 and dashboard_app/static/dashboard_app/images/file-icon.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/icon-fail.png'
Binary files dashboard_app/static/dashboard_app/images/icon-fail.png	2010-12-20 11:48:23 +0000 and dashboard_app/static/dashboard_app/images/icon-fail.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/icon-pass.png'
Binary files dashboard_app/static/dashboard_app/images/icon-pass.png	2010-12-20 11:48:23 +0000 and dashboard_app/static/dashboard_app/images/icon-pass.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/icon-skip.png'
Binary files dashboard_app/static/dashboard_app/images/icon-skip.png	2013-03-20 14:54:38 +0000 and dashboard_app/static/dashboard_app/images/icon-skip.png	1970-01-01 00:00:00 +0000 differ
=== removed file 'dashboard_app/static/dashboard_app/images/icon-unknown.png'
Binary files dashboard_app/static/dashboard_app/images/icon-unknown.png	2010-12-20 11:48:23 +0000 and dashboard_app/static/dashboard_app/images/icon-unknown.png	1970-01-01 00:00:00 +0000 differ
=== removed directory 'dashboard_app/static/dashboard_app/js'
=== removed file 'dashboard_app/static/dashboard_app/js/FixedHeader.min.js'
--- dashboard_app/static/dashboard_app/js/FixedHeader.min.js	2011-07-08 04:20:37 +0000
+++ dashboard_app/static/dashboard_app/js/FixedHeader.min.js	1970-01-01 00:00:00 +0000
@@ -1,115 +0,0 @@
-/*
- * File:        FixedHeader.min.js
- * Version:     2.0.4
- * Author:      Allan Jardine (www.sprymedia.co.uk)
- * 
- * Copyright 2009-2011 Allan Jardine, all rights reserved.
- *
- * This source file is free software, under either the GPL v2 license or a
- * BSD (3 point) style license, as supplied with this software.
- * 
- * This source file is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- */
-var FixedHeader=function(b,a){if(typeof this.fnInit!="function"){alert("FixedHeader warning: FixedHeader must be initialised with the 'new' keyword.");
-return}var c=this;var d={aoCache:[],oSides:{top:true,bottom:false,left:false,right:false},oZIndexes:{top:104,bottom:103,left:102,right:101},oMes:{iTableWidth:0,iTableHeight:0,iTableLeft:0,iTableRight:0,iTableTop:0,iTableBottom:0},nTable:null,bUseAbsPos:false,bFooter:false};
-this.fnGetSettings=function(){return d};this.fnUpdate=function(){this._fnUpdateClones();
-this._fnUpdatePositions()};this.fnInit(b,a)};FixedHeader.prototype={fnInit:function(b,a){var c=this.fnGetSettings();
-var d=this;this.fnInitSettings(c,a);if(typeof b.fnSettings=="function"){if(typeof b.fnVersionCheck=="functon"&&b.fnVersionCheck("1.6.0")!==true){alert("FixedHeader 2 required DataTables 1.6.0 or later. Please upgrade your DataTables installation");
-return}var e=b.fnSettings();if(e.oScroll.sX!=""||e.oScroll.sY!=""){alert("FixedHeader 2 is not supported with DataTables' scrolling mode at this time");
-return}c.nTable=e.nTable;e.aoDrawCallback.push({fn:function(){FixedHeader.fnMeasure();
-d._fnUpdateClones.call(d);d._fnUpdatePositions.call(d)},sName:"FixedHeader"})}else{c.nTable=b
-}c.bFooter=($(">tfoot",c.nTable).length>0)?true:false;c.bUseAbsPos=(jQuery.browser.msie&&(jQuery.browser.version=="6.0"||jQuery.browser.version=="7.0"));
-if(c.oSides.top){c.aoCache.push(d._fnCloneTable("fixedHeader","FixedHeader_Header",d._fnCloneThead))
-}if(c.oSides.bottom){c.aoCache.push(d._fnCloneTable("fixedFooter","FixedHeader_Footer",d._fnCloneTfoot))
-}if(c.oSides.left){c.aoCache.push(d._fnCloneTable("fixedLeft","FixedHeader_Left",d._fnCloneTLeft))
-}if(c.oSides.right){c.aoCache.push(d._fnCloneTable("fixedRight","FixedHeader_Right",d._fnCloneTRight))
-}FixedHeader.afnScroll.push(function(){d._fnUpdatePositions.call(d)});jQuery(window).resize(function(){FixedHeader.fnMeasure();
-d._fnUpdateClones.call(d);d._fnUpdatePositions.call(d)});FixedHeader.fnMeasure();
-d._fnUpdateClones();d._fnUpdatePositions()},fnInitSettings:function(b,a){if(typeof a!="undefined"){if(typeof a.top!="undefined"){b.oSides.top=a.top
-}if(typeof a.bottom!="undefined"){b.oSides.bottom=a.bottom}if(typeof a.left!="undefined"){b.oSides.left=a.left
-}if(typeof a.right!="undefined"){b.oSides.right=a.right}if(typeof a.zTop!="undefined"){b.oZIndexes.top=a.zTop
-}if(typeof a.zBottom!="undefined"){b.oZIndexes.bottom=a.zBottom}if(typeof a.zLeft!="undefined"){b.oZIndexes.left=a.zLeft
-}if(typeof a.zRight!="undefined"){b.oZIndexes.right=a.zRight}}b.bUseAbsPos=(jQuery.browser.msie&&(jQuery.browser.version=="6.0"||jQuery.browser.version=="7.0"))
-},_fnCloneTable:function(f,e,d){var b=this.fnGetSettings();var a;if(jQuery(b.nTable.parentNode).css("position")!="absolute"){b.nTable.parentNode.style.position="relative"
-}a=b.nTable.cloneNode(false);var c=document.createElement("div");c.style.position="absolute";
-c.className+=" FixedHeader_Cloned "+f+" "+e;if(f=="fixedHeader"){c.style.zIndex=b.oZIndexes.top
-}if(f=="fixedFooter"){c.style.zIndex=b.oZIndexes.bottom}if(f=="fixedLeft"){c.style.zIndex=b.oZIndexes.left
-}else{if(f=="fixedRight"){c.style.zIndex=b.oZIndexes.right}}c.appendChild(a);document.body.appendChild(c);
-return{nNode:a,nWrapper:c,sType:f,sPosition:"",sTop:"",sLeft:"",fnClone:d}},_fnMeasure:function(){var d=this.fnGetSettings(),a=d.oMes,c=jQuery(d.nTable),b=c.offset(),f=this._fnSumScroll(d.nTable.parentNode,"scrollTop"),e=this._fnSumScroll(d.nTable.parentNode,"scrollLeft");
-a.iTableWidth=c.outerWidth();a.iTableHeight=c.outerHeight();a.iTableLeft=b.left+d.nTable.parentNode.scrollLeft;
-a.iTableTop=b.top+f;a.iTableRight=a.iTableLeft+a.iTableWidth;a.iTableRight=FixedHeader.oDoc.iWidth-a.iTableLeft-a.iTableWidth;
-a.iTableBottom=FixedHeader.oDoc.iHeight-a.iTableTop-a.iTableHeight},_fnSumScroll:function(c,b){var a=c[b];
-while(c=c.parentNode){if(c.nodeName!="HTML"&&c.nodeName!="BODY"){break}a=c[b]}return a
-},_fnUpdatePositions:function(){var c=this.fnGetSettings();this._fnMeasure();for(var b=0,a=c.aoCache.length;
-b<a;b++){if(c.aoCache[b].sType=="fixedHeader"){this._fnScrollFixedHeader(c.aoCache[b])
-}else{if(c.aoCache[b].sType=="fixedFooter"){this._fnScrollFixedFooter(c.aoCache[b])
-}else{if(c.aoCache[b].sType=="fixedLeft"){this._fnScrollHorizontalLeft(c.aoCache[b])
-}else{this._fnScrollHorizontalRight(c.aoCache[b])}}}}},_fnUpdateClones:function(){var c=this.fnGetSettings();
-for(var b=0,a=c.aoCache.length;b<a;b++){c.aoCache[b].fnClone.call(this,c.aoCache[b])
-}},_fnScrollHorizontalRight:function(g){var e=this.fnGetSettings(),f=e.oMes,b=FixedHeader.oWin,a=FixedHeader.oDoc,d=g.nWrapper,c=jQuery(d).outerWidth();
-if(b.iScrollRight<f.iTableRight){this._fnUpdateCache(g,"sPosition","absolute","position",d.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",d.style);this._fnUpdateCache(g,"sLeft",(f.iTableLeft+f.iTableWidth-c)+"px","left",d.style)
-}else{if(f.iTableLeft<a.iWidth-b.iScrollRight-c){if(e.bUseAbsPos){this._fnUpdateCache(g,"sPosition","absolute","position",d.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",d.style);this._fnUpdateCache(g,"sLeft",(a.iWidth-b.iScrollRight-c)+"px","left",d.style)
-}else{this._fnUpdateCache(g,"sPosition","fixed","position",d.style);this._fnUpdateCache(g,"sTop",(f.iTableTop-b.iScrollTop)+"px","top",d.style);
-this._fnUpdateCache(g,"sLeft",(b.iWidth-c)+"px","left",d.style)}}else{this._fnUpdateCache(g,"sPosition","absolute","position",d.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",d.style);this._fnUpdateCache(g,"sLeft",f.iTableLeft+"px","left",d.style)
-}}},_fnScrollHorizontalLeft:function(g){var e=this.fnGetSettings(),f=e.oMes,b=FixedHeader.oWin,a=FixedHeader.oDoc,c=g.nWrapper,d=jQuery(c).outerWidth();
-if(b.iScrollLeft<f.iTableLeft){this._fnUpdateCache(g,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",c.style);this._fnUpdateCache(g,"sLeft",f.iTableLeft+"px","left",c.style)
-}else{if(b.iScrollLeft<f.iTableLeft+f.iTableWidth-d){if(e.bUseAbsPos){this._fnUpdateCache(g,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",c.style);this._fnUpdateCache(g,"sLeft",b.iScrollLeft+"px","left",c.style)
-}else{this._fnUpdateCache(g,"sPosition","fixed","position",c.style);this._fnUpdateCache(g,"sTop",(f.iTableTop-b.iScrollTop)+"px","top",c.style);
-this._fnUpdateCache(g,"sLeft","0px","left",c.style)}}else{this._fnUpdateCache(g,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",c.style);this._fnUpdateCache(g,"sLeft",(f.iTableLeft+f.iTableWidth-d)+"px","left",c.style)
-}}},_fnScrollFixedFooter:function(h){var f=this.fnGetSettings(),g=f.oMes,b=FixedHeader.oWin,a=FixedHeader.oDoc,c=h.nWrapper,e=jQuery("thead",f.nTable).outerHeight(),d=jQuery(c).outerHeight();
-if(b.iScrollBottom<g.iTableBottom){this._fnUpdateCache(h,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(h,"sTop",(g.iTableTop+g.iTableHeight-d)+"px","top",c.style);this._fnUpdateCache(h,"sLeft",g.iTableLeft+"px","left",c.style)
-}else{if(b.iScrollBottom<g.iTableBottom+g.iTableHeight-d-e){if(f.bUseAbsPos){this._fnUpdateCache(h,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(h,"sTop",(a.iHeight-b.iScrollBottom-d)+"px","top",c.style);this._fnUpdateCache(h,"sLeft",g.iTableLeft+"px","left",c.style)
-}else{this._fnUpdateCache(h,"sPosition","fixed","position",c.style);this._fnUpdateCache(h,"sTop",(b.iHeight-d)+"px","top",c.style);
-this._fnUpdateCache(h,"sLeft",(g.iTableLeft-b.iScrollLeft)+"px","left",c.style)}}else{this._fnUpdateCache(h,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(h,"sTop",(g.iTableTop+d)+"px","top",c.style);this._fnUpdateCache(h,"sLeft",g.iTableLeft+"px","left",c.style)
-}}},_fnScrollFixedHeader:function(g){var d=this.fnGetSettings(),f=d.oMes,b=FixedHeader.oWin,a=FixedHeader.oDoc,c=g.nWrapper,e=d.nTable.getElementsByTagName("tbody")[0].offsetHeight;
-if(f.iTableTop>b.iScrollTop){this._fnUpdateCache(g,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(g,"sTop",f.iTableTop+"px","top",c.style);this._fnUpdateCache(g,"sLeft",f.iTableLeft+"px","left",c.style)
-}else{if(b.iScrollTop>f.iTableTop+e){this._fnUpdateCache(g,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(g,"sTop",(f.iTableTop+e)+"px","top",c.style);this._fnUpdateCache(g,"sLeft",f.iTableLeft+"px","left",c.style)
-}else{if(d.bUseAbsPos){this._fnUpdateCache(g,"sPosition","absolute","position",c.style);
-this._fnUpdateCache(g,"sTop",b.iScrollTop+"px","top",c.style);this._fnUpdateCache(g,"sLeft",f.iTableLeft+"px","left",c.style)
-}else{this._fnUpdateCache(g,"sPosition","fixed","position",c.style);this._fnUpdateCache(g,"sTop","0px","top",c.style);
-this._fnUpdateCache(g,"sLeft",(f.iTableLeft-b.iScrollLeft)+"px","left",c.style)}}}},_fnUpdateCache:function(e,c,b,d,a){if(e[c]!=b){a[d]=b;
-e[c]=b}},_fnCloneThead:function(d){var c=this.fnGetSettings();var a=d.nNode;d.nWrapper.style.width=jQuery(c.nTable).outerWidth()+"px";
-while(a.childNodes.length>0){jQuery("thead th",a).unbind("click");a.removeChild(a.childNodes[0])
-}var b=jQuery("thead",c.nTable).clone(true)[0];a.appendChild(b);jQuery("thead:eq(0)>tr th",c.nTable).each(function(e){jQuery("thead:eq(0)>tr th:eq("+e+")",a).width(jQuery(this).width())
-});jQuery("thead:eq(0)>tr td",c.nTable).each(function(e){jQuery("thead:eq(0)>tr th:eq("+e+")",a)[0].style.width(jQuery(this).width())
-})},_fnCloneTfoot:function(d){var c=this.fnGetSettings();var a=d.nNode;d.nWrapper.style.width=jQuery(c.nTable).outerWidth()+"px";
-while(a.childNodes.length>0){a.removeChild(a.childNodes[0])}var b=jQuery("tfoot",c.nTable).clone(true)[0];
-a.appendChild(b);jQuery("tfoot:eq(0)>tr th",c.nTable).each(function(e){jQuery("tfoot:eq(0)>tr th:eq("+e+")",a).width(jQuery(this).width())
-});jQuery("tfoot:eq(0)>tr td",c.nTable).each(function(e){jQuery("tfoot:eq(0)>tr th:eq("+e+")",a)[0].style.width(jQuery(this).width())
-})},_fnCloneTLeft:function(f){var c=this.fnGetSettings();var b=f.nNode;var e=jQuery("tbody tr:eq(0) td",c.nTable).length;
-var a=($.browser.msie&&($.browser.version=="6.0"||$.browser.version=="7.0"));while(b.childNodes.length>0){b.removeChild(b.childNodes[0])
-}b.appendChild(jQuery("thead",c.nTable).clone(true)[0]);b.appendChild(jQuery("tbody",c.nTable).clone(true)[0]);
-if(c.bFooter){b.appendChild(jQuery("tfoot",c.nTable).clone(true)[0])}jQuery("thead tr th:gt(0)",b).remove();
-jQuery("tfoot tr th:gt(0)",b).remove();$("tbody tr",b).each(function(g){$("td:gt(0)",this).remove();
-if($.browser.mozilla||$.browser.opera){$("td",this).height($("tbody tr:eq("+g+")",that.dom.body).outerHeight())
-}else{$("td",this).height($("tbody tr:eq("+g+")",that.dom.body).outerHeight()-iBoxHack)
-}if(!a){$("tbody tr:eq("+g+")",that.dom.body).height($("tbody tr:eq("+g+")",that.dom.body).outerHeight())
-}});var d=jQuery("thead tr th:eq(0)",c.nTable).outerWidth();b.style.width=d+"px";
-f.nWrapper.style.width=d+"px"},_fnCloneTRight:function(f){var c=this.fnGetSettings();
-var b=f.nNode;var e=jQuery("tbody tr:eq(0) td",c.nTable).length;var a=($.browser.msie&&($.browser.version=="6.0"||$.browser.version=="7.0"));
-while(b.childNodes.length>0){b.removeChild(b.childNodes[0])}b.appendChild(jQuery("thead",c.nTable).clone(true)[0]);
-b.appendChild(jQuery("tbody",c.nTable).clone(true)[0]);if(c.bFooter){b.appendChild(jQuery("tfoot",c.nTable).clone(true)[0])
-}jQuery("thead tr th:not(:nth-child("+e+"n))",b).remove();jQuery("tfoot tr th:not(:nth-child("+e+"n))",b).remove();
-$("tbody tr",b).each(function(g){$("td:lt("+e-1+")",this).remove();if($.browser.mozilla||$.browser.opera){$("td",this).height($("tbody tr:eq("+g+")",that.dom.body).outerHeight())
-}else{$("td",this).height($("tbody tr:eq("+g+")",that.dom.body).outerHeight()-iBoxHack)
-}if(!a){$("tbody tr:eq("+g+")",that.dom.body).height($("tbody tr:eq("+g+")",that.dom.body).outerHeight())
-}});var d=jQuery("thead tr th:eq("+(e-1)+")",c.nTable).outerWidth();b.style.width=d+"px";
-f.nWrapper.style.width=d+"px"}};FixedHeader.oWin={iScrollTop:0,iScrollRight:0,iScrollBottom:0,iScrollLeft:0,iHeight:0,iWidth:0};
-FixedHeader.oDoc={iHeight:0,iWidth:0};FixedHeader.afnScroll=[];FixedHeader.fnMeasure=function(){var d=jQuery(window),c=jQuery(document),b=FixedHeader.oWin,a=FixedHeader.oDoc;
-a.iHeight=c.height();a.iWidth=c.width();b.iHeight=d.height();b.iWidth=d.width();b.iScrollTop=d.scrollTop();
-b.iScrollLeft=d.scrollLeft();b.iScrollRight=a.iWidth-b.iScrollLeft-b.iWidth;b.iScrollBottom=a.iHeight-b.iScrollTop-b.iHeight
-};jQuery(window).scroll(function(){FixedHeader.fnMeasure();for(var b=0,a=FixedHeader.afnScroll.length;
-b<a;b++){FixedHeader.afnScroll[b]()}});
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/excanvas.min.js'
--- dashboard_app/static/dashboard_app/js/excanvas.min.js	2011-05-03 20:08:05 +0000
+++ dashboard_app/static/dashboard_app/js/excanvas.min.js	1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-if(!document.createElement("canvas").getContext){(function(){var z=Math;var K=z.round;var J=z.sin;var U=z.cos;var b=z.abs;var k=z.sqrt;var D=10;var F=D/2;function T(){return this.context_||(this.context_=new W(this))}var O=Array.prototype.slice;function G(i,j,m){var Z=O.call(arguments,2);return function(){return i.apply(j,Z.concat(O.call(arguments)))}}function AD(Z){return String(Z).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function r(i){if(!i.namespaces.g_vml_){i.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!i.namespaces.g_o_){i.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!i.styleSheets.ex_canvas_){var Z=i.createStyleSheet();Z.owningElement.id="ex_canvas_";Z.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}r(document);var E={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var i=Z||document;i.createElement("canvas");i.attachEvent("onreadystatechange",G(this.init_,this,i))}},init_:function(m){var j=m.getElementsByTagName("canvas");for(var Z=0;Z<j.length;Z++){this.initElement(j[Z])}},initElement:function(i){if(!i.getContext){i.getContext=T;r(i.ownerDocument);i.innerHTML="";i.attachEvent("onpropertychange",S);i.attachEvent("onresize",w);var Z=i.attributes;if(Z.width&&Z.width.specified){i.style.width=Z.width.nodeValue+"px"}else{i.width=i.clientWidth}if(Z.height&&Z.height.specified){i.style.height=Z.height.nodeValue+"px"}else{i.height=i.clientHeight}}return i}};function S(i){var Z=i.srcElement;switch(i.propertyName){case"width":Z.getContext().clearRect();Z.style.width=Z.attributes.width.nodeValue+"px";Z.firstChild.style.width=Z.clientWidth+"px";break;case"height":Z.getContext().clearRect();Z.style.height=Z.attributes.height.nodeValue+"px";Z.firstChild.style.height=Z.clientHeight+"px";break}}function w(i){var Z=i.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}E.init();var I=[];for(var AC=0;AC<16;AC++){for(var AB=0;AB<16;AB++){I[AC*16+AB]=AC.toString(16)+AB.toString(16)}}function V(){return[[1,0,0],[0,1,0],[0,0,1]]}function d(m,j){var i=V();for(var Z=0;Z<3;Z++){for(var AF=0;AF<3;AF++){var p=0;for(var AE=0;AE<3;AE++){p+=m[Z][AE]*j[AE][AF]}i[Z][AF]=p}}return i}function Q(i,Z){Z.fillStyle=i.fillStyle;Z.lineCap=i.lineCap;Z.lineJoin=i.lineJoin;Z.lineWidth=i.lineWidth;Z.miterLimit=i.miterLimit;Z.shadowBlur=i.shadowBlur;Z.shadowColor=i.shadowColor;Z.shadowOffsetX=i.shadowOffsetX;Z.shadowOffsetY=i.shadowOffsetY;Z.strokeStyle=i.strokeStyle;Z.globalAlpha=i.globalAlpha;Z.font=i.font;Z.textAlign=i.textAlign;Z.textBaseline=i.textBaseline;Z.arcScaleX_=i.arcScaleX_;Z.arcScaleY_=i.arcScaleY_;Z.lineScale_=i.lineScale_}var B={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function g(i){var m=i.indexOf("(",3);var Z=i.indexOf(")",m+1);var j=i.substring(m+1,Z).split(",");if(j.length==4&&i.substr(3,1)=="a"){alpha=Number(j[3])}else{j[3]=1}return j}function C(Z){return parseFloat(Z)/100}function N(i,j,Z){return Math.min(Z,Math.max(j,i))}function c(AF){var j,i,Z;h=parseFloat(AF[0])/360%360;if(h<0){h++}s=N(C(AF[1]),0,1);l=N(C(AF[2]),0,1);if(s==0){j=i=Z=l}else{var m=l<0.5?l*(1+s):l+s-l*s;var AE=2*l-m;j=A(AE,m,h+1/3);i=A(AE,m,h);Z=A(AE,m,h-1/3)}return"#"+I[Math.floor(j*255)]+I[Math.floor(i*255)]+I[Math.floor(Z*255)]}function A(i,Z,j){if(j<0){j++}if(j>1){j--}if(6*j<1){return i+(Z-i)*6*j}else{if(2*j<1){return Z}else{if(3*j<2){return i+(Z-i)*(2/3-j)*6}else{return i}}}}function Y(Z){var AE,p=1;Z=String(Z);if(Z.charAt(0)=="#"){AE=Z}else{if(/^rgb/.test(Z)){var m=g(Z);var AE="#",AF;for(var j=0;j<3;j++){if(m[j].indexOf("%")!=-1){AF=Math.floor(C(m[j])*255)}else{AF=Number(m[j])}AE+=I[N(AF,0,255)]}p=m[3]}else{if(/^hsl/.test(Z)){var m=g(Z);AE=c(m);p=m[3]}else{AE=B[Z]||Z}}}return{color:AE,alpha:p}}var L={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var f={};function X(Z){if(f[Z]){return f[Z]}var m=document.createElement("div");var j=m.style;try{j.font=Z}catch(i){}return f[Z]={style:j.fontStyle||L.style,variant:j.fontVariant||L.variant,weight:j.fontWeight||L.weight,size:j.fontSize||L.size,family:j.fontFamily||L.family}}function P(j,i){var Z={};for(var AF in j){Z[AF]=j[AF]}var AE=parseFloat(i.currentStyle.fontSize),m=parseFloat(j.size);if(typeof j.size=="number"){Z.size=j.size}else{if(j.size.indexOf("px")!=-1){Z.size=m}else{if(j.size.indexOf("em")!=-1){Z.size=AE*m}else{if(j.size.indexOf("%")!=-1){Z.size=(AE/100)*m}else{if(j.size.indexOf("pt")!=-1){Z.size=m/0.75}else{Z.size=AE}}}}}Z.size*=0.981;return Z}function AA(Z){return Z.style+" "+Z.variant+" "+Z.weight+" "+Z.size+"px "+Z.family}function t(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function W(i){this.m_=V();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=D*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var Z=i.ownerDocument.createElement("div");Z.style.width=i.clientWidth+"px";Z.style.height=i.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";i.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var M=W.prototype;M.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};M.beginPath=function(){this.currentPath_=[]};M.moveTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"moveTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.lineTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"lineTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.bezierCurveTo=function(j,i,AI,AH,AG,AE){var Z=this.getCoords_(AG,AE);var AF=this.getCoords_(j,i);var m=this.getCoords_(AI,AH);e(this,AF,m,Z)};function e(Z,m,j,i){Z.currentPath_.push({type:"bezierCurveTo",cp1x:m.x,cp1y:m.y,cp2x:j.x,cp2y:j.y,x:i.x,y:i.y});Z.currentX_=i.x;Z.currentY_=i.y}M.quadraticCurveTo=function(AG,j,i,Z){var AF=this.getCoords_(AG,j);var AE=this.getCoords_(i,Z);var AH={x:this.currentX_+2/3*(AF.x-this.currentX_),y:this.currentY_+2/3*(AF.y-this.currentY_)};var m={x:AH.x+(AE.x-this.currentX_)/3,y:AH.y+(AE.y-this.currentY_)/3};e(this,AH,m,AE)};M.arc=function(AJ,AH,AI,AE,i,j){AI*=D;var AN=j?"at":"wa";var AK=AJ+U(AE)*AI-F;var AM=AH+J(AE)*AI-F;var Z=AJ+U(i)*AI-F;var AL=AH+J(i)*AI-F;if(AK==Z&&!j){AK+=0.125}var m=this.getCoords_(AJ,AH);var AG=this.getCoords_(AK,AM);var AF=this.getCoords_(Z,AL);this.currentPath_.push({type:AN,x:m.x,y:m.y,radius:AI,xStart:AG.x,yStart:AG.y,xEnd:AF.x,yEnd:AF.y})};M.rect=function(j,i,Z,m){this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath()};M.strokeRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.stroke();this.currentPath_=p};M.fillRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.fill();this.currentPath_=p};M.createLinearGradient=function(i,m,Z,j){var p=new v("gradient");p.x0_=i;p.y0_=m;p.x1_=Z;p.y1_=j;return p};M.createRadialGradient=function(m,AE,j,i,p,Z){var AF=new v("gradientradial");AF.x0_=m;AF.y0_=AE;AF.r0_=j;AF.x1_=i;AF.y1_=p;AF.r1_=Z;return AF};M.drawImage=function(AO,j){var AH,AF,AJ,AV,AM,AK,AQ,AX;var AI=AO.runtimeStyle.width;var AN=AO.runtimeStyle.height;AO.runtimeStyle.width="auto";AO.runtimeStyle.height="auto";var AG=AO.width;var AT=AO.height;AO.runtimeStyle.width=AI;AO.runtimeStyle.height=AN;if(arguments.length==3){AH=arguments[1];AF=arguments[2];AM=AK=0;AQ=AJ=AG;AX=AV=AT}else{if(arguments.length==5){AH=arguments[1];AF=arguments[2];AJ=arguments[3];AV=arguments[4];AM=AK=0;AQ=AG;AX=AT}else{if(arguments.length==9){AM=arguments[1];AK=arguments[2];AQ=arguments[3];AX=arguments[4];AH=arguments[5];AF=arguments[6];AJ=arguments[7];AV=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AW=this.getCoords_(AH,AF);var m=AQ/2;var i=AX/2;var AU=[];var Z=10;var AE=10;AU.push(" <g_vml_:group",' coordsize="',D*Z,",",D*AE,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",AE,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var p=[];p.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",K(AW.x/D),",","Dy=",K(AW.y/D),"");var AS=AW;var AR=this.getCoords_(AH+AJ,AF);var AP=this.getCoords_(AH,AF+AV);var AL=this.getCoords_(AH+AJ,AF+AV);AS.x=z.max(AS.x,AR.x,AP.x,AL.x);AS.y=z.max(AS.y,AR.y,AP.y,AL.y);AU.push("padding:0 ",K(AS.x/D),"px ",K(AS.y/D),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",p.join(""),", sizingmethod='clip');")}else{AU.push("top:",K(AW.y/D),"px;left:",K(AW.x/D),"px;")}AU.push(' ">','<g_vml_:image src="',AO.src,'"',' style="width:',D*AJ,"px;"," height:",D*AV,'px"',' cropleft="',AM/AG,'"',' croptop="',AK/AT,'"',' cropright="',(AG-AM-AQ)/AG,'"',' cropbottom="',(AT-AK-AX)/AT,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",AU.join(""))};M.stroke=function(AM){var m=10;var AN=10;var AE=5000;var AG={x:null,y:null};var AL={x:null,y:null};for(var AH=0;AH<this.currentPath_.length;AH+=AE){var AK=[];var AF=false;AK.push("<g_vml_:shape",' filled="',!!AM,'"',' style="position:absolute;width:',m,"px;height:",AN,'px;"',' coordorigin="0,0"',' coordsize="',D*m,",",D*AN,'"',' stroked="',!AM,'"',' path="');var AO=false;for(var AI=AH;AI<Math.min(AH+AE,this.currentPath_.length);AI++){if(AI%AE==0&&AI>0){AK.push(" m ",K(this.currentPath_[AI-1].x),",",K(this.currentPath_[AI-1].y))}var Z=this.currentPath_[AI];var AJ;switch(Z.type){case"moveTo":AJ=Z;AK.push(" m ",K(Z.x),",",K(Z.y));break;case"lineTo":AK.push(" l ",K(Z.x),",",K(Z.y));break;case"close":AK.push(" x ");Z=null;break;case"bezierCurveTo":AK.push(" c ",K(Z.cp1x),",",K(Z.cp1y),",",K(Z.cp2x),",",K(Z.cp2y),",",K(Z.x),",",K(Z.y));break;case"at":case"wa":AK.push(" ",Z.type," ",K(Z.x-this.arcScaleX_*Z.radius),",",K(Z.y-this.arcScaleY_*Z.radius)," ",K(Z.x+this.arcScaleX_*Z.radius),",",K(Z.y+this.arcScaleY_*Z.radius)," ",K(Z.xStart),",",K(Z.yStart)," ",K(Z.xEnd),",",K(Z.yEnd));break}if(Z){if(AG.x==null||Z.x<AG.x){AG.x=Z.x}if(AL.x==null||Z.x>AL.x){AL.x=Z.x}if(AG.y==null||Z.y<AG.y){AG.y=Z.y}if(AL.y==null||Z.y>AL.y){AL.y=Z.y}}}AK.push(' ">');if(!AM){R(this,AK)}else{a(this,AK,AG,AL)}AK.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",AK.join(""))}};function R(j,AE){var i=Y(j.strokeStyle);var m=i.color;var p=i.alpha*j.globalAlpha;var Z=j.lineScale_*j.lineWidth;if(Z<1){p*=Z}AE.push("<g_vml_:stroke",' opacity="',p,'"',' joinstyle="',j.lineJoin,'"',' miterlimit="',j.miterLimit,'"',' endcap="',t(j.lineCap),'"',' weight="',Z,'px"',' color="',m,'" />')}function a(AO,AG,Ah,AP){var AH=AO.fillStyle;var AY=AO.arcScaleX_;var AX=AO.arcScaleY_;var Z=AP.x-Ah.x;var m=AP.y-Ah.y;if(AH instanceof v){var AL=0;var Ac={x:0,y:0};var AU=0;var AK=1;if(AH.type_=="gradient"){var AJ=AH.x0_/AY;var j=AH.y0_/AX;var AI=AH.x1_/AY;var Aj=AH.y1_/AX;var Ag=AO.getCoords_(AJ,j);var Af=AO.getCoords_(AI,Aj);var AE=Af.x-Ag.x;var p=Af.y-Ag.y;AL=Math.atan2(AE,p)*180/Math.PI;if(AL<0){AL+=360}if(AL<0.000001){AL=0}}else{var Ag=AO.getCoords_(AH.x0_,AH.y0_);Ac={x:(Ag.x-Ah.x)/Z,y:(Ag.y-Ah.y)/m};Z/=AY*D;m/=AX*D;var Aa=z.max(Z,m);AU=2*AH.r0_/Aa;AK=2*AH.r1_/Aa-AU}var AS=AH.colors_;AS.sort(function(Ak,i){return Ak.offset-i.offset});var AN=AS.length;var AR=AS[0].color;var AQ=AS[AN-1].color;var AW=AS[0].alpha*AO.globalAlpha;var AV=AS[AN-1].alpha*AO.globalAlpha;var Ab=[];for(var Ae=0;Ae<AN;Ae++){var AM=AS[Ae];Ab.push(AM.offset*AK+AU+" "+AM.color)}AG.push('<g_vml_:fill type="',AH.type_,'"',' method="none" focus="100%"',' color="',AR,'"',' color2="',AQ,'"',' colors="',Ab.join(","),'"',' opacity="',AV,'"',' g_o_:opacity2="',AW,'"',' angle="',AL,'"',' focusposition="',Ac.x,",",Ac.y,'" />')}else{if(AH instanceof u){if(Z&&m){var AF=-Ah.x;var AZ=-Ah.y;AG.push("<g_vml_:fill",' position="',AF/Z*AY*AY,",",AZ/m*AX*AX,'"',' type="tile"',' src="',AH.src_,'" />')}}else{var Ai=Y(AO.fillStyle);var AT=Ai.color;var Ad=Ai.alpha*AO.globalAlpha;AG.push('<g_vml_:fill color="',AT,'" opacity="',Ad,'" />')}}}M.fill=function(){this.stroke(true)};M.closePath=function(){this.currentPath_.push({type:"close"})};M.getCoords_=function(j,i){var Z=this.m_;return{x:D*(j*Z[0][0]+i*Z[1][0]+Z[2][0])-F,y:D*(j*Z[0][1]+i*Z[1][1]+Z[2][1])-F}};M.save=function(){var Z={};Q(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=d(V(),this.m_)};M.restore=function(){if(this.aStack_.length){Q(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function H(Z){return isFinite(Z[0][0])&&isFinite(Z[0][1])&&isFinite(Z[1][0])&&isFinite(Z[1][1])&&isFinite(Z[2][0])&&isFinite(Z[2][1])}function y(i,Z,j){if(!H(Z)){return }i.m_=Z;if(j){var p=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];i.lineScale_=k(b(p))}}M.translate=function(j,i){var Z=[[1,0,0],[0,1,0],[j,i,1]];y(this,d(Z,this.m_),false)};M.rotate=function(i){var m=U(i);var j=J(i);var Z=[[m,j,0],[-j,m,0],[0,0,1]];y(this,d(Z,this.m_),false)};M.scale=function(j,i){this.arcScaleX_*=j;this.arcScaleY_*=i;var Z=[[j,0,0],[0,i,0],[0,0,1]];y(this,d(Z,this.m_),true)};M.transform=function(p,m,AF,AE,i,Z){var j=[[p,m,0],[AF,AE,0],[i,Z,1]];y(this,d(j,this.m_),true)};M.setTransform=function(AE,p,AG,AF,j,i){var Z=[[AE,p,0],[AG,AF,0],[j,i,1]];y(this,Z,true)};M.drawText_=function(AK,AI,AH,AN,AG){var AM=this.m_,AQ=1000,i=0,AP=AQ,AF={x:0,y:0},AE=[];var Z=P(X(this.font),this.element_);var j=AA(Z);var AR=this.element_.currentStyle;var p=this.textAlign.toLowerCase();switch(p){case"left":case"center":case"right":break;case"end":p=AR.direction=="ltr"?"right":"left";break;case"start":p=AR.direction=="rtl"?"right":"left";break;default:p="left"}switch(this.textBaseline){case"hanging":case"top":AF.y=Z.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":AF.y=-Z.size/2.25;break}switch(p){case"right":i=AQ;AP=0.05;break;case"center":i=AP=AQ/2;break}var AO=this.getCoords_(AI+AF.x,AH+AF.y);AE.push('<g_vml_:line from="',-i,' 0" to="',AP,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!AG,'" stroked="',!!AG,'" style="position:absolute;width:1px;height:1px;">');if(AG){R(this,AE)}else{a(this,AE,{x:-i,y:0},{x:AP,y:Z.size})}var AL=AM[0][0].toFixed(3)+","+AM[1][0].toFixed(3)+","+AM[0][1].toFixed(3)+","+AM[1][1].toFixed(3)+",0,0";var AJ=K(AO.x/D)+","+K(AO.y/D);AE.push('<g_vml_:skew on="t" matrix="',AL,'" ',' offset="',AJ,'" origin="',i,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',AD(AK),'" style="v-text-align:',p,";font:",AD(j),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",AE.join(""))};M.fillText=function(j,Z,m,i){this.drawText_(j,Z,m,i,false)};M.strokeText=function(j,Z,m,i){this.drawText_(j,Z,m,i,true)};M.measureText=function(j){if(!this.textMeasureEl_){var Z='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",Z);this.textMeasureEl_=this.element_.lastChild}var i=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(i.createTextNode(j));return{width:this.textMeasureEl_.offsetWidth}};M.clip=function(){};M.arcTo=function(){};M.createPattern=function(i,Z){return new u(i,Z)};function v(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}v.prototype.addColorStop=function(i,Z){Z=Y(Z);this.colors_.push({offset:i,color:Z.color,alpha:Z.alpha})};function u(i,Z){q(i);switch(Z){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=Z;break;default:n("SYNTAX_ERR")}this.src_=i.src;this.width_=i.width;this.height_=i.height}function n(Z){throw new o(Z)}function q(Z){if(!Z||Z.nodeType!=1||Z.tagName!="IMG"){n("TYPE_MISMATCH_ERR")}if(Z.readyState!="complete"){n("INVALID_STATE_ERR")}}function o(Z){this.code=this[Z];this.message=Z+": DOM Exception "+this.code}var x=o.prototype=new Error;x.INDEX_SIZE_ERR=1;x.DOMSTRING_SIZE_ERR=2;x.HIERARCHY_REQUEST_ERR=3;x.WRONG_DOCUMENT_ERR=4;x.INVALID_CHARACTER_ERR=5;x.NO_DATA_ALLOWED_ERR=6;x.NO_MODIFICATION_ALLOWED_ERR=7;x.NOT_FOUND_ERR=8;x.NOT_SUPPORTED_ERR=9;x.INUSE_ATTRIBUTE_ERR=10;x.INVALID_STATE_ERR=11;x.SYNTAX_ERR=12;x.INVALID_MODIFICATION_ERR=13;x.NAMESPACE_ERR=14;x.INVALID_ACCESS_ERR=15;x.VALIDATION_ERR=16;x.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=E;CanvasRenderingContext2D=W;CanvasGradient=v;CanvasPattern=u;DOMException=o})()};
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/filter-detail.js'
--- dashboard_app/static/dashboard_app/js/filter-detail.js	2013-01-10 01:34:27 +0000
+++ dashboard_app/static/dashboard_app/js/filter-detail.js	1970-01-01 00:00:00 +0000
@@ -1,135 +0,0 @@
-var compareState = 0;
-var compare1 = null, compare2 = null;
-function cancelCompare () {
-    $("#filter-table").removeClass("select-compare1");
-    $("#filter-table").removeClass("select-compare2");
-    $("#filter-table").removeClass("select-compare3");
-    $("#filter-table tr").removeClass("selected-1");
-    $("#filter-table tr").removeClass("selected-2");
-    $("#filter-table tr").unbind("click");
-    $("#filter-table tr").unbind("hover");
-    $("#filter-table tr").each(removeCheckbox);
-    $("#first-prompt").hide();
-    $("#second-prompt").hide();
-    $("#third-prompt").hide();
-    $("#compare-button").button({label:"Compare builds"});
-    compareState = 0;
-}
-function startCompare () {
-    $("#compare-button").button({label:"Cancel"});
-    $("#filter-table").addClass("select-compare1");
-    $("#filter-table tr").click(rowClickHandler);
-    $("#filter-table tr").each(insertCheckbox);
-    $("#filter-table tr").hover(rowHoverHandlerIn, rowHoverHandlerOut);
-    $("#first-prompt").show();
-    compareState = 1;
-}
-function tagFromRow(tr) {
-    var firstCell = $(tr).find("td:eq(0)");
-    return {
-        machinetag: firstCell.find("span").data("machinetag"),
-        usertag: firstCell.text()
-    };
-}
-function rowClickHandler() {
-    if (compareState == 1) {
-        compare1 = tagFromRow($(this));
-        $(this).addClass("selected-1");
-        $(this).find("input").attr("checked", true);
-        $("#p2-build").text(compare1.usertag);
-        $("#first-prompt").hide();
-        $("#second-prompt").show();
-        $("#filter-table").removeClass("select-compare1");
-        $("#filter-table").addClass("select-compare2");
-        compareState = 2;
-    } else if (compareState == 2) {
-        var thistag = tagFromRow($(this));
-        if (compare1.machinetag == thistag.machinetag) {
-            cancelCompare();
-            startCompare();
-        } else {
-            compare2 = thistag;
-            $(this).find("input").attr("checked", true);
-            $(this).addClass("selected-2");
-            $("#second-prompt").hide();
-            $("#third-prompt").show();
-            $("#filter-table").removeClass("select-compare2");
-            $("#filter-table").addClass("select-compare3");
-            $("#filter-table input").attr("disabled", true);
-            $("#filter-table .selected-1 input").attr("disabled", false);
-            $("#filter-table .selected-2 input").attr("disabled", false);
-            $("#p3-build-1").text(compare1.usertag);
-            $("#p3-build-2").text(compare2.usertag);
-            $("#third-prompt a").attr("href", window.location + '/+compare/' + compare1.machinetag + '/' + compare2.machinetag);
-            compareState = 3;
-        }
-    } else if (compareState == 3) {
-        var thistag = tagFromRow($(this));
-        if (thistag.machinetag == compare1.machinetag || thistag.machinetag == compare2.machinetag) {
-            $("#second-prompt").show();
-            $("#third-prompt").hide();
-            $("#filter-table").addClass("select-compare2");
-            $("#filter-table").removeClass("select-compare3");
-            $("#filter-table input").attr("disabled", false);
-            compareState = 2;
-            $(this).find("input").attr("checked", false);
-            if (thistag.machinetag == compare1.machinetag) {
-                compare1 = compare2;
-                $("#filter-table .selected-1").removeClass("selected-1");
-                $("#filter-table .selected-2").addClass("selected-1");
-                $("#p2-build").text(compare1.usertag);
-            }
-            $("#filter-table .selected-2").removeClass("selected-2");
-        }
-    }
-    tagFromRow(this);
-}
-function rowHoverHandlerIn() {
-    $(this).addClass("hover");
-}
-function rowHoverHandlerOut() {
-    $(this).removeClass("hover");
-}
-function insertCheckbox() {
-    var row = $(this);
-    var checkbox = $('<input type="checkbox">');
-    row.find("td:first").prepend(checkbox);
-}
-function removeCheckbox() {
-    var row = $(this);
-    row.find('input').remove();
-}
-$(window).load(
-    function () {
-        $("#filter-table").dataTable().fnSettings().fnRowCallback = function(tr, data, index) {
-            if (compareState) {
-                insertCheckbox.call(tr);
-                $(tr).click(rowClickHandler);
-                $("#filter-table tr").hover(rowHoverHandlerIn, rowHoverHandlerOut);
-                if (compareState >= 2 && tagFromRow(tr).machinetag == compare1.machinetag) {
-                    $(tr).addClass("selected-1");
-                    $(tr).find("input").attr("checked", true);
-                }
-                if (compareState >= 3) {
-                    if (tagFromRow(tr).machinetag == compare2.machinetag) {
-                        $(tr).addClass("selected-2");
-                        $(tr).find("input").attr("checked", true);
-                    } else if (tagFromRow(tr).machinetag != compare1.machinetag) {
-                        $(tr).find("input").attr("disabled", true);
-                    }
-                }
-            }
-            return tr;
-        };
-        $("#compare-button").button();
-        $("#compare-button").click(
-            function (e) {
-                if (compareState == 0) {
-                    startCompare();
-                } else {
-                    cancelCompare();
-                }
-            }
-        );
-    }
-);

=== removed file 'dashboard_app/static/dashboard_app/js/filter-edit.js'
--- dashboard_app/static/dashboard_app/js/filter-edit.js	2012-09-20 22:17:38 +0000
+++ dashboard_app/static/dashboard_app/js/filter-edit.js	1970-01-01 00:00:00 +0000
@@ -1,133 +0,0 @@
-$(function () {
-function updateTestCasesFromTest() {
-    var test_id=$(this).find("option:selected").html();
-    var selects = $(this).closest('tr').find('.test-case-formset select');
-    selects.each(
-        function () {
-            $(this).empty();
-        });
-    $.ajax(
-        {
-            url: test_case_url + test_id,
-            dataType: 'json',
-            success: function (data) {
-                selects.each(
-                    function () {
-                        var select = $(this);
-                        $(data).each(
-                            function (index, val) {
-                                var test_case_id = val.test_case_id;
-                                if (test_case_id.length > 50) {
-                                    test_case_id = test_case_id.substring(0, 50) + "...";
-                                }
-                                select.append(new Option(test_case_id, val.id));
-                            });
-                        select.removeAttr("disabled");
-                    });
-            }
-        });
-};
-
-$("#id_tests_empty_form .test-case-formset-empty select").attr('disabled', 'disabled');
-$(".test-cell select").change(updateTestCasesFromTest);
-
-var nameAutocompleteConfig = {
-        source: attr_name_completion_url
-    };
-
-var valueAutocompleteConfig = {
-        source: function (request, response) {
-            var attrName = this.element.closest('tr').find('.name input').val();
-            $.getJSON(
-                attr_value_completion_url,
-                {
-                    'name': attrName,
-                    'term': request.term
-                },
-                function (data) {
-                    response(data);
-                }
-            );
-        }
-    };
-
-$("tbody .name input").autocomplete(nameAutocompleteConfig);
-$("tbody .value input").autocomplete(valueAutocompleteConfig);
-
-$("#attributes-table tbody tr").formset(
-    {
-        formTemplate: '#id_attributes_empty_form',
-        prefix: "attributes",
-        formCssClass: "attributes-dynamic-form",
-        addText: "Add a required attribute",
-        added: function(row) {
-            row.find(".name input").unbind();
-            row.find(".name input").autocomplete(nameAutocompleteConfig);
-            row.find(".value input").unbind();
-            row.find(".value input").autocomplete(valueAutocompleteConfig);
-        }
-    });
-
-var formsetCallCount = 0;
-
-function formsetTestCase(test_row) {
-    var addText;
-    if (test_row.find(".test-case-formset select").size() < 2) {
-        addText = 'Specify test cases';
-    } else {
-        addText = 'Add another test case';
-        test_row.find('> td:last').hide();
-    }
-
-    var index = test_row.parent().children('.test-dynamic-form').index(test_row);
-
-    var fs = test_row.find(".test-case-formset > tbody > tr").formset(
-        {
-            formTemplate: test_row.find(".test-case-formset-empty"),
-            formCssClass: "test-cases-dynamic-form-" + formsetCallCount,
-            addText: addText,
-            deleteText: "Remove test case",
-            prefix: "tests-" + index,
-            added: function (row2) {
-                test_row.find('.add-row').text('Add another test case');
-                test_row.find('> td:last').hide();
-            },
-            removed: function (row2) {
-                if (test_row.find(".test-case-formset select").size() < 2) {
-                    test_row.find('.add-row').text("Specify test cases");
-                    test_row.find('> td:last').show();
-                }
-            }
-        }
-    );
-
-    test_row.data('formset', fs);
-
-    formsetCallCount += 1;
-}
-
-$("#tests-table > tbody > tr").formset(
-    {
-        formTemplate: '#id_tests_empty_form',
-        prefix: "tests",
-        formCssClass: "test-dynamic-form",
-        addText: "Add a test",
-        deleteText: "Remove test",
-        added: formsetTestCase,
-        removed: function () {
-            $("#tests-table > tbody > tr.test-dynamic-form").each(
-                function () {
-                    var index = $(this).parent().children('.test-dynamic-form').index($(this));
-                    $(this).data('formset').data('options').prefix = 'tests-' + index;
-                });
-        }
-    }
-);
-
-$("#tests-table > tbody > tr").each(
-    function () {
-        formsetTestCase($(this));
-    }
-);
-
-});
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/image-report-editor.js'
--- dashboard_app/static/dashboard_app/js/image-report-editor.js	2013-09-12 14:24:11 +0000
+++ dashboard_app/static/dashboard_app/js/image-report-editor.js	1970-01-01 00:00:00 +0000
@@ -1,221 +0,0 @@
-select_filter = function() {
-    // Open the filter select dialog.
-    $('#filter_select_dialog').dialog('open');
-}
-
-filters_callback = function(id, name) {
-    // Function which will be called when a filter is selected from the dialog.
-
-    if ($('#id_chart_type').val() == "pass/fail") {
-        url = "/dashboard/filters/+get-tests-json";
-    } else {
-        url = "/dashboard/filters/+get-test-cases-json";
-    }
-
-    $.ajax({
-        url: url,
-        async: false,
-        data: {"id": id},
-        beforeSend: function () {
-            $('#filter-container').remove();
-            $('#filter_select_dialog').dialog('close');
-            $('#loading_dialog').dialog('open');
-        },
-        success: function (data) {
-            $('#loading_dialog').dialog('close');
-            $("#id_filter").val(id);
-            add_filter_container(data, name);
-        },
-        error: function(data, status, error) {
-            $('#loading_dialog').dialog('close');
-            alert('Filter could not be loaded, please try again.');
-        }
-    });
-}
-
-add_filter_container = function(data, title) {
-    // Adds elements which contain tests or test cases from the previously
-    // selected filter.
-
-    content = '<hr><div class="filter-title">' + title + '</div>';
-
-    if ($('#id_chart_type').val() == "pass/fail") {
-        test_label = "Tests";
-    } else {
-        test_label = "Test Cases";
-    }
-
-    content += '<div class="selector"><div class="selector-available"><h2>' +
-        'Select ' + test_label + '</h2>';
-
-    content += '<select id="available_tests" multiple class="filtered">';
-    for (i in data) {
-        if ($('#id_chart_type').val() == "pass/fail") {
-            content += '<option value="' + data[i].pk + '">' +
-                data[i].fields.test_id + '</option>';
-        } else {
-            content += '<option value="' + data[i].pk + '">' +
-                data[i].fields.test_case_id + '</option>';
-        }
-    }
-    content += '</select>';
-
-    content += '<a id="add_all_link" href="javascript: void(0)">' +
-        'Choose All</a>';
-    content += '</div>';
-
-    content += '<ul class="selector-chooser">' +
-        '<li><a href="javascript: void(0)" id="add_link"' +
-        'class="selector-add active"></a></li>' +
-        '<li><a href="javascript: void(0)" id="remove_link"' +
-        'class="selector-remove active"></a></li>' +
-        '</ul>';
-
-    content += '<div class="selector-chosen"><h2>' +
-        'Choosen ' + test_label + '</h2>';
-
-    content += '<select id="chosen_tests" onchange="toggle_alias()" multiple class="filtered"></select>';
-    content += '<a id="remove_all_link" href="javascript: void(0)">' +
-        'Remove All</a>';
-    content += '</div></div>';
-
-    content += '<div id="alias_container">Alias<br/>';
-    content += '<input type="text" onkeyup="copy_alias(this);" id="alias" />';
-    content += '</div>';
-
-    $('<div id="filter-container"></div>').html(
-        content).appendTo($('#filters_div'));
-
-    update_events();
-}
-
-update_events = function() {
-    // Add onclick events to the links controlling the select boxes.
-
-    $('#add_link').click(function() {
-        move_options('available_tests', 'chosen_tests');
-    });
-    $('#remove_link').click(function() {
-        move_options('chosen_tests', 'available_tests');
-    });
-    $('#add_all_link').click(function() {
-        $('#available_tests option').each(function() {
-            $(this).attr('selected', 'selected');
-        });
-        move_options('available_tests', 'chosen_tests');
-    });
-    $('#remove_all_link').click(function() {
-        $('#chosen_tests option').each(function() {
-            $(this).attr('selected', 'selected');
-        });
-        move_options('chosen_tests', 'available_tests');
-    });
-}
-
-move_options = function(from_element, to_element) {
-    var options = $("#" + from_element + " option:selected");
-    $("#" + to_element).append(options.clone());
-    $(options).remove();
-
-    update_aliases();
-    toggle_alias();
-}
-
-add_selected_options = function() {
-    // Adds options from chosen tests select box as hidden fields.
-
-    $('#chosen_tests option').each(function() {
-        if ($('#id_chart_type').val() == "pass/fail") {
-            field_name = "image_chart_tests";
-        } else {
-            field_name = "image_chart_test_cases";
-        }
-        $('<input type="hidden" name="' + field_name +
-          '" value="'+ $(this).val() + '" />').appendTo($('#add_filter_link'));
-    });
-}
-
-update_aliases = function() {
-    // Update hidden aliases inputs based on chosen tests.
-
-    $('#chosen_tests option').each(function() {
-        if ($('#alias_' + $(this).val()).length == 0) {
-            $('<input type="hidden" class="alias" data-sid="' + $(this).val() +
-              '" name="aliases" id="alias_' + $(this).val() +
-              '" />').appendTo($('#aliases_div'));
-        }
-    });
-    chosen_tests = $.map($('#chosen_tests option'), function(e) {
-        return e.value;
-    });
-    $('.alias').each(function(index, value) {
-        test_id = value.id.split('_')[1];
-
-        if (chosen_tests.indexOf(test_id) == -1) {
-            $('#alias_' + test_id).remove();
-        }
-    });
-}
-
-toggle_alias = function() {
-    // Show/hide alias input field.
-
-    if ($('#chosen_tests option:selected').length == 1) {
-        $('#alias_container').show();
-        test_id = $('#chosen_tests option:selected').val();
-        $('#alias').val($('#alias_' + test_id).val());
-    } else {
-        $('#alias_container').hide();
-    }
-}
-
-copy_alias = function(e) {
-    // Populate alias input based on the selected test.
-
-    if ($('#chosen_tests option:selected').length == 1) {
-        test_id = $('#chosen_tests option:selected').val();
-        $('#alias_' + test_id).val(e.value);
-    }
-}
-
-sort_aliases = function() {
-    // Pre submit function. Sort the aliases hidden inputs.
-
-    $('#aliases_div input').sort(function(a,b) {
-        return a.dataset.sid > b.dataset.sid;
-    }).appendTo('#aliases_div');
-}
-
-init_filter_dialog = function() {
-    // Setup the filter table dialog.
-
-    var filter_dialog = $('<div id="filter_select_dialog"></div>');
-    $('#all-filters_wrapper').wrapAll(filter_dialog);
-
-    $('#filter_select_dialog').dialog({
-        autoOpen: false,
-        title: 'Select Filter',
-        draggable: false,
-        height: 280,
-        width: 420,
-        modal: true,
-        resizable: false
-    });
-}
-
-init_loading_dialog = function() {
-    // Setup the loading image dialog.
-
-    $('#loading_dialog').dialog({
-        autoOpen: false,
-        title: '',
-        draggable: false,
-        height: 35,
-        width: 250,
-        modal: true,
-        resizable: false,
-        dialogClass: 'loading-dialog'
-    });
-
-    $('.loading-dialog div.ui-dialog-titlebar').hide();
-}

=== removed file 'dashboard_app/static/dashboard_app/js/image-report.js'
--- dashboard_app/static/dashboard_app/js/image-report.js	2013-08-14 12:25:50 +0000
+++ dashboard_app/static/dashboard_app/js/image-report.js	1970-01-01 00:00:00 +0000
@@ -1,530 +0,0 @@
-function _resize() {
-    // I couldn't figure out how to do this in CSS: resize the table
-    // so that it takes as much space as it can without expanding the
-    // page horizontally.
-    var space = parseInt($("#lava-breadcrumbs").outerWidth() - $("#outer-table").outerWidth());
-    space -= $("#lava-content").outerWidth() - $("#lava-content").width();
-    var table = $("#results-table"), scroller=$("#scroller");
-    var atRight = scroller.width() + scroller.scrollLeft() >= table.attr('scrollWidth');
-    scroller.width(scroller.width() + space);
-    if (atRight) scroller.scrollLeft(table.attr('scrollWidth'));
-}
-function _fixRowHeights () {
-    var index = 0;
-    var nameRows = $("#test-run-names > tbody > tr");
-    var resultRows = $("#results-table > tbody > tr");
-    for (; index < nameRows.length; index++) {
-        var nameRow = $(nameRows[index]);
-        var resultRow = $(resultRows[index]);
-        var nameRowHeight = parseInt(nameRow.css('height'));
-        var resultRowHeight = parseInt(resultRow.css('height'));
-        nameRow.css('height', Math.max(nameRowHeight, resultRowHeight));
-        resultRow.css('height', Math.max(nameRowHeight, resultRowHeight));
-    }
-}
-
-function toggle_graph () {
-    $("#outer-container").toggle();
-    $(".tickLabels").toggle();
-    update_plot(columns, chart_data, test_names);
-    store_filters();
-}
-
-function update_filters(column_data, test_run_names) {
-    for (iter in column_data) {
-	build_number = column_data[iter]["number"].split('.')[0];
-	build_date = column_data[iter]["date"];
-	$("#build_number_start").append($('<option>', {
-	    value: build_date,
-	    text: build_number
-	}));
-	$("#build_number_end").append($('<option>', {
-	    value: build_date,
-	    text: build_number
-	}));
-    }
-    start_number_options = $("#build_number_start option").size();
-    // Show last 15 options.
-    if (start_number_options > 15) {
-        start_number_options -= 15;
-        $("#build_number_start option:eq(" + start_number_options + ")").attr("selected", true);
-    }
-    $("#build_number_end option:last").attr("selected", true);
-
-    for (iter in test_run_names) {
-	selected = false;
-	if (column_data[column_data.length-1]["test_runs"][test_run_names[iter]]) {
-	    selected = true;
-	}
-	$("#test_select").append($('<option>', {
-	    value: test_run_names[iter],
-	    text: test_run_names[iter],
-	    selected: selected
-	}));
-    }
-
-    // Use jStorage to load the filter values from browser.
-    load_filters();
-}
-
-function update_table(column_data, table_data, test_run_names) {
-
-    if ($("#test_select").val() == null) {
-	alert("Please select at least one test.");
-	return false;
-    }
-
-    build_number_start = $("#build_number_start").val();
-    if (isNumeric(build_number_start)) {
-	build_number_start = parseInt(build_number_start);
-    }
-    build_number_end = $("#build_number_end").val();
-    if (isNumeric(build_number_end)) {
-	build_number_end = parseInt(build_number_end);
-    }
-
-    if (build_number_start > build_number_end) {
-	alert("End build number must be greater then the start build number.");
-	return false;
-    }
-
-    if ($("#target_goal").val() && !isNumeric($("#target_goal").val())) {
-	alert("Target goal must be a numeric value.");
-	return false;
-    }
-
-
-    // Create row headlines.
-    test_name_rows = "<tr><td>Date</td></tr>";
-    for (iter in test_run_names) {
-	if ($("#test_select").val().indexOf(test_run_names[iter]) >= 0) {
-	    test_name = test_run_names[iter];
-	    if (test_name.length > 20) {
-		test_name = test_name.substring(0,20) + "...";
-	    }
-	    test_name_rows += "<tr><td tooltip='" + test_run_names[iter] + "'>" + test_name + "</td></tr>";
-	}
-    }
-    $("#test-run-names tbody").html(test_name_rows);
-
-    // Create column headlines.
-    result_table_head = "<tr>";
-    for (iter in column_data) {
-	if (test_build_number(column_data, iter)) {
-
-	    build_number = column_data[iter]["number"].split('.')[0];
-	    if (!isNumeric(build_number)) {
-		build_number = format_date(build_number.split(' ')[0]);
-	    }
-	    link = '<a href="' + column_data[iter]["link"] + '">' + build_number + '</a>';
-	    result_table_head += "<th>" + link + "</th>";
-	}
-    }
-    result_table_head += "</tr>";
-    $("#results-table thead").html(result_table_head);
-
-    // Create table body
-    result_table_body = "<tr>";
-    for (iter in column_data) {
-	build_date = column_data[iter]["date"].split('.')[0];
-
-	if (test_build_number(column_data, iter)) {
-	    result_table_body += "<td>" + format_date(build_date.split(' ')[0]) + "</td>";
-	}
-
-    }
-    result_table_body += "</tr>";
-
-    for (cnt in test_run_names) {
-	test = test_run_names[cnt];
-	if ($("#test_select").val().indexOf(test) >= 0) {
-	    result_table_body += "<tr>";
-	    row = table_data[test];
-
-	    for (iter in row) {
-
-		if (test_build_number(column_data, iter)) {
-		    result_table_body += '<td class="' + row[iter]["cls"] + '" data-uuid="' + row[iter]["uuid"] + '">';
-		    if (row[iter]["uuid"]) {
-			result_table_body += '<a href="' + row[iter]["link"] + '">' + row[iter]["passes"] + '/' + row[iter]["total"] + '</a>';
-			result_table_body += '<span class="bug-links">';
-			for (bug_id in row[iter]["bug_ids"]) {
-			    bug = row[iter]["bug_ids"];
-			    result_table_body += '<a class="bug-link" href="https://bugs.launchpad.net/bugs/' + bug[bug_id] + '" data-bug-id="' + bug[bug_id] + '">[' + bug[bug_id] + ']</a>';
-			}
-			result_table_body += '<a href="#" class="add-bug-link">[+]</a>';
-			result_table_body += '</span>';
-
-		    } else {
-			result_table_body += "&mdash;";
-		    }
-		    result_table_body += "</td>";
-		}
-	    }
-	    result_table_body += "</tr>";
-	}
-    }
-
-    $("#results-table tbody").html(result_table_body);
-    $("#scroller").scrollLeft($("#scroller")[0].scrollWidth);
-
-    // Use jStorage to save filter values to the browser.
-    store_filters();
-    update_plot(column_data, table_data, test_run_names);
-    update_tooltips();
-    update_filter_link();
-    add_bug_links();
-    _fixRowHeights();
-}
-
-function update_filter_link() {
-    filter_link = window.location.href.split('?')[0] + '?';
-    filter_link += "build_number_start=" + $("#build_number_start").val();
-    filter_link += "&build_number_end=" + $("#build_number_end").val();
-    filter_link += "&test_select=" + $("#test_select").val();
-    filter_link += "&target_goal=" + $("#target_goal").val().trim();
-    filter_link += "&graph_type=" + $('input:radio[name=graph_type]:checked').val();
-
-    $("#filter_link").attr("href", filter_link);
-}
-
-function update_tooltips() {
-    // Update tooltips on the remaining td's for the test names.
-    $("td", "#test-run-names").each(function () {
-	if ($(this).attr('tooltip')) {
-	    $(this).tooltip({
-		bodyHandler: function() {
-		    return $(this).attr('tooltip');
-		}
-	    });
-	}
-    });
-}
-
-function store_filters() {
-    // Use jStorage to save filter values to the browser.
-
-    prefix = window.location.pathname.split('/').pop();
-
-    $.jStorage.set(prefix + "_target_goal", $("#target_goal").val().trim());
-    $.jStorage.set(prefix + "_build_number_start", $("#build_number_start").val());
-    $.jStorage.set(prefix + "_test_select", $("#test_select").val());
-    $.jStorage.set(prefix + "_toggle_graph", $("#toggle_graph").attr("checked"));
-    $.jStorage.set(prefix + "_graph_type", $('input:radio[name=graph_type]:checked').val());
-}
-
-function load_filters() {
-    // Use jStorage to load the filter values from browser.
-
-    // If get parameters are present they are used because of higher priority.
-    if (location.search != "") {
-	populate_filters_from_get();
-	return;
-    }
-
-    prefix = window.location.pathname.split('/').pop();
-
-    if ($.jStorage.get(prefix + "_target_goal")) {
-	$("#target_goal").val($.jStorage.get(prefix + "_target_goal"));
-    }
-    if ($.jStorage.get(prefix + "_build_number_start")) {
-	$("#build_number_start").val($.jStorage.get(prefix + "_build_number_start"));
-    }
-    if ($.jStorage.get(prefix + "_test_select")) {
-	$("#test_select").val($.jStorage.get(prefix + "_test_select"));
-    }
-    if ($.jStorage.get(prefix + "_toggle_graph") != null) {
-	$("#toggle_graph").attr("checked", $.jStorage.get(prefix + "_toggle_graph"));
-    }
-    if ($.jStorage.get(prefix + "_graph_type")) {
-	if ($.jStorage.get(prefix + "_graph_type") == "number") {
-	    $('input:radio[name=graph_type][value="number"]').attr("checked", true);
-	} else if ($.jStorage.get(prefix + "_graph_type") == "percentage") {
-	    $('input:radio[name=graph_type][value="percentage"]').attr("checked", true);
-	} else { // measurements
-	    $('input:radio[name=graph_type][value="measurements"]').attr("checked", true);
-	}
-    }
-}
-
-function populate_filters_from_get() {
-    // Populate filter fields from get request parameters.
-    var parameters = get_parameters_from_request();
-    for (iter in parameters) {
-	if (parameters[iter][0] == "build_number_start" && parameters[iter][1] != "") {
-	    $("#build_number_start").val(unescape(parameters[iter][1]));
-	}
-	if (parameters[iter][0] == "build_number_end" && parameters[iter][1] != "") {
-	    $("#build_number_end").val(unescape(parameters[iter][1]));
-	}
-	if (parameters[iter][0] == "test_select" && parameters[iter][1] != "") {
-	    $("#test_select").val(parameters[iter][1].split(','));
-	}
-	if (parameters[iter][0] == "target_goal" && parameters[iter][1] != "") {
-	    $("#target_goal").val(unescape(parameters[iter][1]));
-	}
-	if (parameters[iter][0] == "graph_type" && parameters[iter][1] != "") {
-	    if (parameters[iter][1] == "number") {
-		$('input:radio[name=graph_type][value="number"]').attr("checked", true);
-	    } else if (parameters[iter][1] == "percentage") {
-		$('input:radio[name=graph_type][value="percentage"]').attr("checked", true);
-	    } else { // measurements
-		$('input:radio[name=graph_type][value="measurements"]').attr("checked", true);
-	    }
-	}
-    }
-}
-
-function get_parameters_from_request() {
-    var params = location.search.replace('?', '').split('&').map(function(val) {	
-	return val.split('=');
-    });
-    return params;
-}
-
-function update_plot(column_data, table_data, test_run_names) {
-
-    // Get the plot data.
-
-    data = [];
-    for (test in table_data) {
-
-	if ($("#test_select").val().indexOf(test) >= 0) {
-	    row_data = [];
-
-	    row = table_data[test];
-	    for (iter in row) {
-
-		if (test_build_number(column_data, iter)) {
-		    if (row[iter]["cls"]) {
-			if ($('input:radio[name=graph_type]:checked').val() == "number") {
-			    row_data.push([iter, row[iter]["passes"]]); 
-			} else if ($('input:radio[name=graph_type]:checked').val() == "percentage") {
-			    if (isNaN(row[iter]["passes"]/row[iter]["total"])) {
-				row_data.push([iter, 0]);
-			    } else {
-				row_data.push([iter, 100*row[iter]["passes"]/row[iter]["total"]]);
-			    }
-			} else { // measurements
-			    if (row[iter]["measurements"] && row[iter]["measurements"].length != 0) {
-				row_data.push([iter, row[iter]["measurements"][0]["measurement"]]);
-			    }
-			}
-		    }
-		}
-	    }
-	    data.push({label: test, data: row_data});
-	}
-    }
-
-    // Add target goal dashed line to the plot.
-    if ($("#target_goal").val()) {
-	row_data = [];
-	row = table_data[test_run_names[0]];
-	for (iter in row) {
-	    if (test_build_number(column_data, iter)) {
-		row_data.push([iter, $("#target_goal").val()]);
-	    }
-	}
-	data.push({data: row_data, dashes: {show: true}, lines: {show: false}, color: "#000000"});
-    }
-
-    // Get all build numbers to be used as tick labels.
-    build_numbers = [];
-    for (test in table_data) {
-	row = table_data[test];
-	for (iter in row) {
-	    build_number = column_data[iter]["number"].split(' ')[0];
-	    if (!isNumeric(build_number)) {
-		build_number = format_date(build_number);
-	    }
-	    build_numbers.push(build_number);
-	}
-	// Each test has the same number of build numbers.
-	break;
-    }
-
-    var options = {
-	series: {
-	    lines: { show: true },
-	    points: { show: false }
-	},
-	legend: {
-	    show: true,
-	    position: "ne",
-	    margin: 3,
-	    container: "#legend-container",
-	    labelFormatter: function(label, series) {
-		if (label.length > 20) {
-		    return label.substring(0,20) + "...";
-		}
-		return label;
-	    },
-	},
-	xaxis: {
-	    tickDecimals: 0,
-	    tickFormatter: function (val, axis) {
-		return build_numbers[val];
-	    },
-	},
-	yaxis: {
-	    tickDecimals: 0,
-	},
-    };
-
-    if ($('input:radio[name=graph_type]:checked').val() == "percentage") {
-	options["yaxis"]["max"] = 100;
-	options["yaxis"]["min"] = 0;
-    }
-
-    $.plot($("#outer-container #inner-container"), data, options); 
-}
-
-function test_build_number(column_data, iter) {
-    // Test if the build number/date is between specified number/date boundaries.
-
-    var build_number = column_data[iter]["date"];
-
-    if (build_number <= $("#build_number_end").val() && build_number >= $("#build_number_start").val()) {
-	return true;
-    }
-
-    return false;
-}
-
-function isNumeric(n) {
-    return !isNaN(parseFloat(n)) && isFinite(n);
-}
-
-function format_date(date_string) {
-    date = $.datepicker.parseDate("yy-mm-dd", date_string);
-    date_string = $.datepicker.formatDate("M d, yy", date);
-    return date_string;
-}
-
-function add_bug_links() {
-
-    function _submit() {
-        $(this).submit();
-    }
-    var add_bug_dialog = $('#add-bug-dialog').dialog(
-        {
-            autoOpen: false,
-            buttons: {'Cancel': function () {$(this).dialog('close');}, 'OK': _submit },
-            modal: true,
-            title: "Link bug to XXX"
-        });
-    var go_to_bug_dialog = $("#go-to-bug-dialog").dialog(
-        {
-            autoOpen: false,
-            buttons: {'Cancel': function () {$(this).dialog('close');}, 'Remove link': _submit},
-            modal: true,
-            title: "Link bug to XXX"
-        });
-
-    function get_testrun_and_buildnumber (element) {
-        var cell = element.closest('td');
-        var row = cell.closest('tr');
-        var testrun = $($("#test-run-names > tbody > tr")[row.index()]).text();
-        var header_cells = element.closest('table').find('thead > tr > th');
-        var buildnumber = $(header_cells[cell.index()]).text();
-        return {testrun: $.trim(testrun), buildnumber: $.trim(buildnumber)};
-    }
-
-    function find_previous_bugs (element) {
-        var td = $(element).closest('td');
-        var bugs = [];
-        var start = td;
-        while ((td = td.prev()) && td.size()) {
-            td.find(".bug-link").each(
-                function (index, link) {
-                    var bug_id = $(link).data('bug-id');
-                    if (bugs.indexOf(bug_id) < 0) bugs.push(bug_id);
-                });
-        }
-        var already_linked = [];
-        start.find(".bug-link").each(
-            function (index, link) {
-                var bug_id = $(link).data('bug-id');
-                if (bugs.indexOf(bug_id) >= 0) {
-                    bugs.splice(bugs.indexOf(bug_id), 1);
-                    already_linked.push(bug_id);
-                }
-            });
-        return {bugs:bugs, already_linked:already_linked};
-    }
-
-    $('a.add-bug-link').click(
-        function (e) {
-            e.preventDefault();
-
-            var previous = find_previous_bugs($(this));
-            var prev_div = add_bug_dialog.find('div.prev');
-            var names = get_testrun_and_buildnumber($(this));
-
-            if (previous.bugs.length) {
-                var html = '';
-                prev_div.show();
-                html = '<p>Use a bug previously linked to ' + names.testrun + ':</p><ul>';
-                for (var i = 0; i < previous.already_linked.length; i++) {
-                    html += '<li><span style="text-decoration: line-through">' + previous.already_linked[i] + '</span> (already linked)</li>';
-                }
-                for (var i = 0; i < previous.bugs.length; i++) {
-                    html += '<li><a href="#" data-bug-id="' + previous.bugs[i] + '">' +
-                        previous.bugs[i] + '</a></li>';
-                }
-                html += '</ul>';
-                html += "<p>Or enter another bug number:</p>";
-                prev_div.html(html);
-                prev_div.find('a').click(
-                    function (e) {
-                        e.preventDefault();
-                        add_bug_dialog.find('input[name=bug]').val($(this).data('bug-id'));
-                        add_bug_dialog.submit();
-                    });
-            } else {
-                prev_div.hide();
-            }
-
-            var title = "Link a bug to the '" + names.testrun +
-                "' run of build " + names.buildnumber;
-            add_bug_dialog.find('input[name=uuid]').val($(this).closest('td').data('uuid'));
-            add_bug_dialog.dialog('option', 'title', title);
-            add_bug_dialog.dialog('open');
-        });
-
-    $("a.bug-link").click(
-        function (e) {
-            e.preventDefault();
-            var names = get_testrun_and_buildnumber($(this));
-            var title = "Bug linked to the '" + names.testrun +
-                "' run of build " + names.buildnumber;
-            go_to_bug_dialog.find('input[name=uuid]').val($(this).closest('td').data('uuid'));
-            go_to_bug_dialog.find('input[name=bug]').val($(this).data('bug-id'));
-            go_to_bug_dialog.find('a').attr('href', $(this).attr('href'));
-            go_to_bug_dialog.find('a').text('View bug ' + $(this).data('bug-id'));
-            go_to_bug_dialog.dialog('option', 'title', title);
-            go_to_bug_dialog.dialog('open');
-        });
-}
-
-$(window).ready(
-    function () {
-	update_filters(columns, test_names);
-	update_table(columns, chart_data, test_names);
-        // Hook up the event and run resize ASAP (looks jumpy in FF if you
-        // don't run it here).
-        $(window).resize(_resize);
-        _resize();
-        _fixRowHeights();
-
-	add_bug_links();
-	if (!$("#toggle_graph").attr("checked")) {
-	    $("#outer-container").toggle();
-	}
-    });
-// Because what resize does depends on the final sizes of elements,
-// run it again after everything is loaded (things end up wrong in
-// chromium if you don't do this).
-$(window).load(_resize);
-$(window).load(_fixRowHeights);

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.dashboard.js'
--- dashboard_app/static/dashboard_app/js/jquery.dashboard.js	2011-10-21 00:22:23 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.dashboard.js	1970-01-01 00:00:00 +0000
@@ -1,125 +0,0 @@
-/* Dashboard plugin for jQuery */
-(function($) {
-  var _server = null;
-  var _url = null;
-  var _global_table_id = 0;
-
-  function query_data_view(data_view_name, data_view_arguments, callback) {
-    _server.query_data_view(callback, data_view_name, data_view_arguments);
-  }
-
-  var methods = {
-    init: function(url, callback) {
-      if (_server == null) {
-        _url = url;
-        _server = $.rpc(url, "xml", callback, "2.0");
-      } else {
-        _server = $.rpc(url, "xml", callback, "2.0");
-      }
-      return _server;
-    },
-
-    graph: function(options) {
-      return this.each(function() {
-        var $this = $(this);
-        var plot_data = {
-          options: options,
-          series: []
-        };
-        $this.data('dashboard', plot_data);
-        $.plot($this, plot_data.series, plot_data.options);
-      });
-    },
-
-    add_series: function(query) {
-      return this.each(function() {
-        var $this = $(this);
-        var plot_data = $this.data('dashboard');
-        if (!plot_data) {
-          plot_data = {
-            options: {},
-            series: []
-          };
-          $this.data('dashboard', plot_data);
-        }
-        query_data_view(query.data_view.name, query.data_view.args, function(response) {
-          if (response.result) {
-            plot_data.series.push({
-              data: response.result.rows,
-              label: query.label
-            });
-            $.plot($this, plot_data.series, plot_data.options);
-          } else {
-            alert("Query failed: "+ response.error.faultString + " (code: " + response.error.faultCode + ")");
-          }
-        });
-      });
-    },
-
-    render_table: function(dataset, options) {
-      var table_id = _global_table_id++;
-      var html = "<table class='demo_jui display' id='dashboard_table_" + table_id + "'>";
-      if (options != undefined && options.caption != undefined) {
-        html += "<caption>" + options.caption + "</caption>";
-      }
-      html += "<thead><tr>";
-      $.each(dataset.columns, function (index, column) {
-        html += "<th>" + column.name + "</th>";
-      });
-      html += "</tr></thead><tbody>";
-      $.each(dataset.rows, function (index, row) {
-        html += "<tr>";
-        $.each(row, function (index, cell) {
-          var column = dataset.columns[index];
-          var cell_html = undefined;
-          var cell_link = null;
-          if (cell_html == undefined) {
-            cell_html = cell;
-          }
-          if (column.name == "UUID") {
-            /* This is a bit hacky but will work for now */
-            cell_link = _url + ".." + "/permalink/test-run/" + cell + "/";
-          }
-          html += "<td>";
-          if (cell_link) {
-            html += "<a href='" + cell_link + "'>"
-            html += cell_html;
-            html += "</a>";
-          } else {
-            html += cell_html;
-          }
-          html += "</td>";
-        });
-        html += "</tr>";
-      });
-      html += "</tbody></table>";
-      this.html(html);
-      $("#dashboard_table_" + table_id).dataTable({
-        "bJQueryUI": true,
-        "sPaginationType": "full_numbers",
-      });
-    },
-
-    render_to_table: function(data_view_name, data_view_arguments, options) {
-      var $this = $(this);
-      _server.query_data_view(function (response) {
-        if (response.result) {
-          $this.dashboard("render_table", response.result, options);
-        } else {
-          $this.html("Error code:" + response.error.faultCode + ", message: " + response.error.faultString);
-        }
-      }, data_view_name, data_view_arguments);
-    }
-
-  };
-
-  $.fn.dashboard = function(method) {
-    if (methods[method]) {
-      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
-    } else if (typeof method == "object" || !method) {
-      return methods.init.apply(this, arguments);
-    } else {
-      $.error("Method " + method + "does not exist on jQuery.dashboard");
-    }
-  };
-})(jQuery);

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.flot.axislabels.js'
--- dashboard_app/static/dashboard_app/js/jquery.flot.axislabels.js	2011-05-05 01:22:07 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.flot.axislabels.js	1970-01-01 00:00:00 +0000
@@ -1,87 +0,0 @@
-/*
-Flot plugin for labeling axis
-
-    (xy)axis: {
-        label: "label string",
-        labelPos: "high" or "low"
-    }
-
-This plugin allows you to label an axis without much fuss, by
-replacing one of the extreme ticks with the chosen label string. Set
-labelPos to "high" or "low" to replace respectively the maximum or the
-minimum value of the ticks. User set axis.tickFormatter are respected
-and multiple axes supported.
-
-Rui Pereira
-rui (dot) pereira (at) gmail (dot) com
-*/
-(function ($) {
-
-    function labelAxis(val, axis){
-        var ticks, opts = axis.options;
-
-        // generator
-        var tmpopts = axis.n == 1? opts: (typeof opts.alignedTo != 'undefined')? opts.alignedTo.options: null;
-        // first axis or some axis aligned wrt it
-        if (tmpopts && (tmpopts.autoscaleMargin == null ||
-                (tmpopts.labelPos == 'high' && tmpopts.max != null) ||
-                (tmpopts.labelPos == 'low' && tmpopts.min != null)))
-            // cut ticks not seen
-            ticks = $.grep(axis.tickGenerator(axis), function(v){
-                return (v > axis.min && v < axis.max);
-            });
-        // standard tick generator
-        else ticks = axis.tickGenerator(axis);
-
-        // formatter
-        if ((opts.labelPos == 'high' && val == ticks[ticks.length-1]) ||
-                (opts.labelPos == 'low' && val == ticks[0]))
-            return opts.label;
-        else {
-            // user set tickFormatter
-            if ($.isFunction(opts.userFormatter)){
-                var tmp = opts.userFormatter;
-                // avoid infinite loops
-                opts.userFormatter = null;
-                return tmp(val, axis);
-            } else {
-                // scientific notation for small values
-                if ((axis.datamax != 0 && Math.abs(axis.datamax) < 1e-5) ||
-                        (axis.datamin != 0 && Math.abs(axis.datamin) < 1e-5))
-                    return val.toPrecision(2);
-                else return val.toFixed(axis.tickDecimals);
-            }
-        }
-    }
-
-    function init(plot){
-        plot.hooks.processOptions.push(function(plot, options){
-            // separate X and Y
-            $.each({x: options.xaxes, y: options.yaxes}, function(direction, axes){
-                // get only axes with labels
-                $.each($.grep(axes, function(v){
-                    return (typeof v.label != 'undefined' && v.label);
-                }), function(i, axis){
-                    if ($.isFunction(axis.tickFormatter))
-                        axis.userFormatter = axis.tickFormatter;
-                    if (typeof axis.alignTicksWithAxis != 'undefined')
-                        $.each(plot.getAxes(), function(k,v){
-                            if (v.n == axis.alignTicksWithAxis && v.direction == direction)
-                                axis.alignedTo = v;
-                        });
-                    axis.tickFormatter = labelAxis;
-                });
-            });
-        });
-    }
-
-    var options = { xaxis: {label: null, labelPos: 'high'},
-                    yaxis: {label: null, labelPos: 'high'} };
-
-    $.plot.plugins.push({
-                init: init,
-                options: options,
-                name: "axislabels",
-                version: "0.1"
-            });
-})(jQuery);

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.flot.dashes.min.js'
--- dashboard_app/static/dashboard_app/js/jquery.flot.dashes.min.js	2013-06-10 13:43:14 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.flot.dashes.min.js	1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-/*
- * jQuery.flot.dashes
- * 
- * options = {
- *   series: {
- *     dashes: {
- *       
- *       // show
- *       // default: false
- *       // Whether to show dashes for the series.
- *       show: <boolean>,
- *       
- *       // lineWidth
- *       // default: 2
- *       // The width of the dashed line in pixels.
- *       lineWidth: <number>,
- *       
- *       // dashLength
- *       // default: 10
- *       // Controls the length of the individual dashes and the amount of 
- *       // space between them.
- *       // If this is a number, the dashes and spaces will have that length.
- *       // If this is an array, it is read as [ dashLength, spaceLength ]
- *       dashLength: <number> or <array[2]>
- *     }
- *   }
- * }
- */
-(function($){function init(plot){plot.hooks.processDatapoints.push(function(plot,series,datapoints){if(!series.dashes.show)return;plot.hooks.draw.push(function(plot,ctx){var plotOffset=plot.getPlotOffset(),axisx=series.xaxis,axisy=series.yaxis;function plotDashes(xoffset,yoffset){var points=datapoints.points,ps=datapoints.pointsize,prevx=null,prevy=null,dashRemainder=0,dashOn=true,dashOnLength,dashOffLength;if(series.dashes.dashLength[0]){dashOnLength=series.dashes.dashLength[0];if(series.dashes.dashLength[1]){dashOffLength=series.dashes.dashLength[1]}else{dashOffLength=dashOnLength}}else{dashOffLength=dashOnLength=series.dashes.dashLength}ctx.beginPath();for(var i=ps;i<points.length;i+=ps){var x1=points[i-ps],y1=points[i-ps+1],x2=points[i],y2=points[i+1];if(x1==null||x2==null)continue;if(y1<=y2&&y1<axisy.min){if(y2<axisy.min)continue;x1=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.min}else if(y2<=y1&&y2<axisy.min){if(y1<axisy.min)continue;x2=(axisy.min-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.min}if(y1>=y2&&y1>axisy.max){if(y2>axisy.max)continue;x1=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y1=axisy.max}else if(y2>=y1&&y2>axisy.max){if(y1>axisy.max)continue;x2=(axisy.max-y1)/(y2-y1)*(x2-x1)+x1;y2=axisy.max}if(x1<=x2&&x1<axisx.min){if(x2<axisx.min)continue;y1=(axisx.min-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.min}else if(x2<=x1&&x2<axisx.min){if(x1<axisx.min)continue;y2=(axisx.min-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.min}if(x1>=x2&&x1>axisx.max){if(x2>axisx.max)continue;y1=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x1=axisx.max}else if(x2>=x1&&x2>axisx.max){if(x1>axisx.max)continue;y2=(axisx.max-x1)/(x2-x1)*(y2-y1)+y1;x2=axisx.max}if(x1!=prevx||y1!=prevy){ctx.moveTo(axisx.p2c(x1)+xoffset,axisy.p2c(y1)+yoffset)}var ax1=axisx.p2c(x1)+xoffset,ay1=axisy.p2c(y1)+yoffset,ax2=axisx.p2c(x2)+xoffset,ay2=axisy.p2c(y2)+yoffset,dashOffset;function lineSegmentOffset(segmentLength){var c=Math.sqrt(Math.pow(ax2-ax1,2)+Math.pow(ay2-ay1,2));if(c<=segmentLength){return{deltaX:ax2-ax1,deltaY:ay2-ay1,distance:c,remainder:segmentLength-c}}else{var xsign=ax2>ax1?1:-1,ysign=ay2>ay1?1:-1;return{deltaX:xsign*Math.sqrt(Math.pow(segmentLength,2)/(1+Math.pow((ay2-ay1)/(ax2-ax1),2))),deltaY:ysign*Math.sqrt(Math.pow(segmentLength,2)-Math.pow(segmentLength,2)/(1+Math.pow((ay2-ay1)/(ax2-ax1),2))),distance:segmentLength,remainder:0}}}do{dashOffset=lineSegmentOffset(dashRemainder>0?dashRemainder:dashOn?dashOnLength:dashOffLength);if(dashOffset.deltaX!=0||dashOffset.deltaY!=0){if(dashOn){ctx.lineTo(ax1+dashOffset.deltaX,ay1+dashOffset.deltaY)}else{ctx.moveTo(ax1+dashOffset.deltaX,ay1+dashOffset.deltaY)}}dashOn=!dashOn;dashRemainder=dashOffset.remainder;ax1+=dashOffset.deltaX;ay1+=dashOffset.deltaY}while(dashOffset.distance>0);prevx=x2;prevy=y2}ctx.stroke()}ctx.save();ctx.translate(plotOffset.left,plotOffset.top);ctx.lineJoin='round';var lw=series.dashes.lineWidth,sw=series.shadowSize;if(lw>0&&sw>0){ctx.lineWidth=sw;ctx.strokeStyle="rgba(0,0,0,0.1)";var angle=Math.PI/18;plotDashes(Math.sin(angle)*(lw/2+sw/2),Math.cos(angle)*(lw/2+sw/2));ctx.lineWidth=sw/2;plotDashes(Math.sin(angle)*(lw/2+sw/4),Math.cos(angle)*(lw/2+sw/4))}ctx.lineWidth=lw;ctx.strokeStyle=series.color;if(lw>0){plotDashes(0,0)}ctx.restore()})})}$.plot.plugins.push({init:init,options:{series:{dashes:{show:false,lineWidth:2,dashLength:10}}},name:'dashes',version:'0.1'})})(jQuery)

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.flot.min.js'
--- dashboard_app/static/dashboard_app/js/jquery.flot.min.js	2011-05-05 00:39:20 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.flot.min.js	1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-/* Javascript plotting library for jQuery, v. 0.7.
- *
- * Released under the MIT license by IOLA, December 2007.
- *
- */
-(function(b){b.color={};b.color.make=function(d,e,g,f){var c={};c.r=d||0;c.g=e||0;c.b=g||0;c.a=f!=null?f:1;c.add=function(h,j){for(var k=0;k<h.length;++k){c[h.charAt(k)]+=j}return c.normalize()};c.scale=function(h,j){for(var k=0;k<h.length;++k){c[h.charAt(k)]*=j}return c.normalize()};c.toString=function(){if(c.a>=1){return"rgb("+[c.r,c.g,c.b].join(",")+")"}else{return"rgba("+[c.r,c.g,c.b,c.a].join(",")+")"}};c.normalize=function(){function h(k,j,l){return j<k?k:(j>l?l:j)}c.r=h(0,parseInt(c.r),255);c.g=h(0,parseInt(c.g),255);c.b=h(0,parseInt(c.b),255);c.a=h(0,c.a,1);return c};c.clone=function(){return b.color.make(c.r,c.b,c.g,c.a)};return c.normalize()};b.color.extract=function(d,e){var c;do{c=d.css(e).toLowerCase();if(c!=""&&c!="transparent"){break}d=d.parent()}while(!b.nodeName(d.get(0),"body"));if(c=="rgba(0, 0, 0, 0)"){c="transparent"}return b.color.parse(c)};b.color.parse=function(c){var d,f=b.color.make;if(d=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c)){return f(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10))}if(d=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c)){return f(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10),parseFloat(d[4]))}if(d=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c)){return f(parseFloat(d[1])*2.55,parseFloat(d[2])*2.55,parseFloat(d[3])*2.55)}if(d=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c)){return f(parseFloat(d[1])*2.55,parseFloat(d[2])*2.55,parseFloat(d[3])*2.55,parseFloat(d[4]))}if(d=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c)){return f(parseInt(d[1],16),parseInt(d[2],16),parseInt(d[3],16))}if(d=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c)){return f(parseInt(d[1]+d[1],16),parseInt(d[2]+d[2],16),parseInt(d[3]+d[3],16))}var e=b.trim(c).toLowerCase();if(e=="transparent"){return f(255,255,255,0)}else{d=a[e]||[0,0,0];return f(d[0],d[1],d[2])}};var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);(function(c){function b(av,ai,J,af){var Q=[],O={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:0.85},xaxis:{show:null,position:"bottom",mode:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null,monthNames:null,timeformat:null,twelveHourClock:false},yaxis:{autoscaleMargin:0.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:false,fillColor:null,steps:false},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null,align:"left",horizontal:false},shadowSize:3},grid:{show:true,aboveData:false,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:false,hoverable:false,autoHighlight:true,mouseActiveRadius:10},hooks:{}},az=null,ad=null,y=null,H=null,A=null,p=[],aw=[],q={left:0,right:0,top:0,bottom:0},G=0,I=0,h=0,w=0,ak={processOptions:[],processRawData:[],processDatapoints:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},aq=this;aq.setData=aj;aq.setupGrid=t;aq.draw=W;aq.getPlaceholder=function(){return av};aq.getCanvas=function(){return az};aq.getPlotOffset=function(){return q};aq.width=function(){return h};aq.height=function(){return w};aq.offset=function(){var aB=y.offset();aB.left+=q.left;aB.top+=q.top;return aB};aq.getData=function(){return Q};aq.getAxes=function(){var aC={},aB;c.each(p.concat(aw),function(aD,aE){if(aE){aC[aE.direction+(aE.n!=1?aE.n:"")+"axis"]=aE}});return aC};aq.getXAxes=function(){return p};aq.getYAxes=function(){return aw};aq.c2p=C;aq.p2c=ar;aq.getOptions=function(){return O};aq.highlight=x;aq.unhighlight=T;aq.triggerRedrawOverlay=f;aq.pointOffset=function(aB){return{left:parseInt(p[aA(aB,"x")-1].p2c(+aB.x)+q.left),top:parseInt(aw[aA(aB,"y")-1].p2c(+aB.y)+q.top)}};aq.shutdown=ag;aq.resize=function(){B();g(az);g(ad)};aq.hooks=ak;F(aq);Z(J);X();aj(ai);t();W();ah();function an(aD,aB){aB=[aq].concat(aB);for(var aC=0;aC<aD.length;++aC){aD[aC].apply(this,aB)}}function F(){for(var aB=0;aB<af.length;++aB){var aC=af[aB];aC.init(aq);if(aC.options){c.extend(true,O,aC.options)}}}function Z(aC){var aB;c.extend(true,O,aC);if(O.xaxis.color==null){O.xaxis.color=O.grid.color}if(O.yaxis.color==null){O.yaxis.color=O.grid.color}if(O.xaxis.tickColor==null){O.xaxis.tickColor=O.grid.tickColor}if(O.yaxis.tickColor==null){O.yaxis.tickColor=O.grid.tickColor}if(O.grid.borderColor==null){O.grid.borderColor=O.grid.color}if(O.grid.tickColor==null){O.grid.tickColor=c.color.parse(O.grid.color).scale("a",0.22).toString()}for(aB=0;aB<Math.max(1,O.xaxes.length);++aB){O.xaxes[aB]=c.extend(true,{},O.xaxis,O.xaxes[aB])}for(aB=0;aB<Math.max(1,O.yaxes.length);++aB){O.yaxes[aB]=c.extend(true,{},O.yaxis,O.yaxes[aB])}if(O.xaxis.noTicks&&O.xaxis.ticks==null){O.xaxis.ticks=O.xaxis.noTicks}if(O.yaxis.noTicks&&O.yaxis.ticks==null){O.yaxis.ticks=O.yaxis.noTicks}if(O.x2axis){O.xaxes[1]=c.extend(true,{},O.xaxis,O.x2axis);O.xaxes[1].position="top"}if(O.y2axis){O.yaxes[1]=c.extend(true,{},O.yaxis,O.y2axis);O.yaxes[1].position="right"}if(O.grid.coloredAreas){O.grid.markings=O.grid.coloredAreas}if(O.grid.coloredAreasColor){O.grid.markingsColor=O.grid.coloredAreasColor}if(O.lines){c.extend(true,O.series.lines,O.lines)}if(O.points){c.extend(true,O.series.points,O.points)}if(O.bars){c.extend(true,O.series.bars,O.bars)}if(O.shadowSize!=null){O.series.shadowSize=O.shadowSize}for(aB=0;aB<O.xaxes.length;++aB){V(p,aB+1).options=O.xaxes[aB]}for(aB=0;aB<O.yaxes.length;++aB){V(aw,aB+1).options=O.yaxes[aB]}for(var aD in ak){if(O.hooks[aD]&&O.hooks[aD].length){ak[aD]=ak[aD].concat(O.hooks[aD])}}an(ak.processOptions,[O])}function aj(aB){Q=Y(aB);ax();z()}function Y(aE){var aC=[];for(var aB=0;aB<aE.length;++aB){var aD=c.extend(true,{},O.series);if(aE[aB].data!=null){aD.data=aE[aB].data;delete aE[aB].data;c.extend(true,aD,aE[aB]);aE[aB].data=aD.data}else{aD.data=aE[aB]}aC.push(aD)}return aC}function aA(aC,aD){var aB=aC[aD+"axis"];if(typeof aB=="object"){aB=aB.n}if(typeof aB!="number"){aB=1}return aB}function m(){return c.grep(p.concat(aw),function(aB){return aB})}function C(aE){var aC={},aB,aD;for(aB=0;aB<p.length;++aB){aD=p[aB];if(aD&&aD.used){aC["x"+aD.n]=aD.c2p(aE.left)}}for(aB=0;aB<aw.length;++aB){aD=aw[aB];if(aD&&aD.used){aC["y"+aD.n]=aD.c2p(aE.top)}}if(aC.x1!==undefined){aC.x=aC.x1}if(aC.y1!==undefined){aC.y=aC.y1}return aC}function ar(aF){var aD={},aC,aE,aB;for(aC=0;aC<p.length;++aC){aE=p[aC];if(aE&&aE.used){aB="x"+aE.n;if(aF[aB]==null&&aE.n==1){aB="x"}if(aF[aB]!=null){aD.left=aE.p2c(aF[aB]);break}}}for(aC=0;aC<aw.length;++aC){aE=aw[aC];if(aE&&aE.used){aB="y"+aE.n;if(aF[aB]==null&&aE.n==1){aB="y"}if(aF[aB]!=null){aD.top=aE.p2c(aF[aB]);break}}}return aD}function V(aC,aB){if(!aC[aB-1]){aC[aB-1]={n:aB,direction:aC==p?"x":"y",options:c.extend(true,{},aC==p?O.xaxis:O.yaxis)}}return aC[aB-1]}function ax(){var aG;var aM=Q.length,aB=[],aE=[];for(aG=0;aG<Q.length;++aG){var aJ=Q[aG].color;if(aJ!=null){--aM;if(typeof aJ=="number"){aE.push(aJ)}else{aB.push(c.color.parse(Q[aG].color))}}}for(aG=0;aG<aE.length;++aG){aM=Math.max(aM,aE[aG]+1)}var aC=[],aF=0;aG=0;while(aC.length<aM){var aI;if(O.colors.length==aG){aI=c.color.make(100,100,100)}else{aI=c.color.parse(O.colors[aG])}var aD=aF%2==1?-1:1;aI.scale("rgb",1+aD*Math.ceil(aF/2)*0.2);aC.push(aI);++aG;if(aG>=O.colors.length){aG=0;++aF}}var aH=0,aN;for(aG=0;aG<Q.length;++aG){aN=Q[aG];if(aN.color==null){aN.color=aC[aH].toString();++aH}else{if(typeof aN.color=="number"){aN.color=aC[aN.color].toString()}}if(aN.lines.show==null){var aL,aK=true;for(aL in aN){if(aN[aL]&&aN[aL].show){aK=false;break}}if(aK){aN.lines.show=true}}aN.xaxis=V(p,aA(aN,"x"));aN.yaxis=V(aw,aA(aN,"y"))}}function z(){var aO=Number.POSITIVE_INFINITY,aI=Number.NEGATIVE_INFINITY,aB=Number.MAX_VALUE,aU,aS,aR,aN,aD,aJ,aT,aP,aH,aG,aC,a0,aX,aL;function aF(a3,a2,a1){if(a2<a3.datamin&&a2!=-aB){a3.datamin=a2}if(a1>a3.datamax&&a1!=aB){a3.datamax=a1}}c.each(m(),function(a1,a2){a2.datamin=aO;a2.datamax=aI;a2.used=false});for(aU=0;aU<Q.length;++aU){aJ=Q[aU];aJ.datapoints={points:[]};an(ak.processRawData,[aJ,aJ.data,aJ.datapoints])}for(aU=0;aU<Q.length;++aU){aJ=Q[aU];var aZ=aJ.data,aW=aJ.datapoints.format;if(!aW){aW=[];aW.push({x:true,number:true,required:true});aW.push({y:true,number:true,required:true});if(aJ.bars.show||(aJ.lines.show&&aJ.lines.fill)){aW.push({y:true,number:true,required:false,defaultValue:0});if(aJ.bars.horizontal){delete aW[aW.length-1].y;aW[aW.length-1].x=true}}aJ.datapoints.format=aW}if(aJ.datapoints.pointsize!=null){continue}aJ.datapoints.pointsize=aW.length;aP=aJ.datapoints.pointsize;aT=aJ.datapoints.points;insertSteps=aJ.lines.show&&aJ.lines.steps;aJ.xaxis.used=aJ.yaxis.used=true;for(aS=aR=0;aS<aZ.length;++aS,aR+=aP){aL=aZ[aS];var aE=aL==null;if(!aE){for(aN=0;aN<aP;++aN){a0=aL[aN];aX=aW[aN];if(aX){if(aX.number&&a0!=null){a0=+a0;if(isNaN(a0)){a0=null}else{if(a0==Infinity){a0=aB}else{if(a0==-Infinity){a0=-aB}}}}if(a0==null){if(aX.required){aE=true}if(aX.defaultValue!=null){a0=aX.defaultValue}}}aT[aR+aN]=a0}}if(aE){for(aN=0;aN<aP;++aN){a0=aT[aR+aN];if(a0!=null){aX=aW[aN];if(aX.x){aF(aJ.xaxis,a0,a0)}if(aX.y){aF(aJ.yaxis,a0,a0)}}aT[aR+aN]=null}}else{if(insertSteps&&aR>0&&aT[aR-aP]!=null&&aT[aR-aP]!=aT[aR]&&aT[aR-aP+1]!=aT[aR+1]){for(aN=0;aN<aP;++aN){aT[aR+aP+aN]=aT[aR+aN]}aT[aR+1]=aT[aR-aP+1];aR+=aP}}}}for(aU=0;aU<Q.length;++aU){aJ=Q[aU];an(ak.processDatapoints,[aJ,aJ.datapoints])}for(aU=0;aU<Q.length;++aU){aJ=Q[aU];aT=aJ.datapoints.points,aP=aJ.datapoints.pointsize;var aK=aO,aQ=aO,aM=aI,aV=aI;for(aS=0;aS<aT.length;aS+=aP){if(aT[aS]==null){continue}for(aN=0;aN<aP;++aN){a0=aT[aS+aN];aX=aW[aN];if(!aX||a0==aB||a0==-aB){continue}if(aX.x){if(a0<aK){aK=a0}if(a0>aM){aM=a0}}if(aX.y){if(a0<aQ){aQ=a0}if(a0>aV){aV=a0}}}}if(aJ.bars.show){var aY=aJ.bars.align=="left"?0:-aJ.bars.barWidth/2;if(aJ.bars.horizontal){aQ+=aY;aV+=aY+aJ.bars.barWidth}else{aK+=aY;aM+=aY+aJ.bars.barWidth}}aF(aJ.xaxis,aK,aM);aF(aJ.yaxis,aQ,aV)}c.each(m(),function(a1,a2){if(a2.datamin==aO){a2.datamin=null}if(a2.datamax==aI){a2.datamax=null}})}function j(aB,aC){var aD=document.createElement("canvas");aD.className=aC;aD.width=G;aD.height=I;if(!aB){c(aD).css({position:"absolute",left:0,top:0})}c(aD).appendTo(av);if(!aD.getContext){aD=window.G_vmlCanvasManager.initElement(aD)}aD.getContext("2d").save();return aD}function B(){G=av.width();I=av.height();if(G<=0||I<=0){throw"Invalid dimensions for plot, width = "+G+", height = "+I}}function g(aC){if(aC.width!=G){aC.width=G}if(aC.height!=I){aC.height=I}var aB=aC.getContext("2d");aB.restore();aB.save()}function X(){var aC,aB=av.children("canvas.base"),aD=av.children("canvas.overlay");if(aB.length==0||aD==0){av.html("");av.css({padding:0});if(av.css("position")=="static"){av.css("position","relative")}B();az=j(true,"base");ad=j(false,"overlay");aC=false}else{az=aB.get(0);ad=aD.get(0);aC=true}H=az.getContext("2d");A=ad.getContext("2d");y=c([ad,az]);if(aC){av.data("plot").shutdown();aq.resize();A.clearRect(0,0,G,I);y.unbind();av.children().not([az,ad]).remove()}av.data("plot",aq)}function ah(){if(O.grid.hoverable){y.mousemove(aa);y.mouseleave(l)}if(O.grid.clickable){y.click(R)}an(ak.bindEvents,[y])}function ag(){if(M){clearTimeout(M)}y.unbind("mousemove",aa);y.unbind("mouseleave",l);y.unbind("click",R);an(ak.shutdown,[y])}function r(aG){function aC(aH){return aH}var aF,aB,aD=aG.options.transform||aC,aE=aG.options.inverseTransform;if(aG.direction=="x"){aF=aG.scale=h/Math.abs(aD(aG.max)-aD(aG.min));aB=Math.min(aD(aG.max),aD(aG.min))}else{aF=aG.scale=w/Math.abs(aD(aG.max)-aD(aG.min));aF=-aF;aB=Math.max(aD(aG.max),aD(aG.min))}if(aD==aC){aG.p2c=function(aH){return(aH-aB)*aF}}else{aG.p2c=function(aH){return(aD(aH)-aB)*aF}}if(!aE){aG.c2p=function(aH){return aB+aH/aF}}else{aG.c2p=function(aH){return aE(aB+aH/aF)}}}function L(aD){var aB=aD.options,aF,aJ=aD.ticks||[],aI=[],aE,aK=aB.labelWidth,aG=aB.labelHeight,aC;function aH(aM,aL){return c('<div style="position:absolute;top:-10000px;'+aL+'font-size:smaller"><div class="'+aD.direction+"Axis "+aD.direction+aD.n+'Axis">'+aM.join("")+"</div></div>").appendTo(av)}if(aD.direction=="x"){if(aK==null){aK=Math.floor(G/(aJ.length>0?aJ.length:1))}if(aG==null){aI=[];for(aF=0;aF<aJ.length;++aF){aE=aJ[aF].label;if(aE){aI.push('<div class="tickLabel" style="float:left;width:'+aK+'px">'+aE+"</div>")}}if(aI.length>0){aI.push('<div style="clear:left"></div>');aC=aH(aI,"width:10000px;");aG=aC.height();aC.remove()}}}else{if(aK==null||aG==null){for(aF=0;aF<aJ.length;++aF){aE=aJ[aF].label;if(aE){aI.push('<div class="tickLabel">'+aE+"</div>")}}if(aI.length>0){aC=aH(aI,"");if(aK==null){aK=aC.children().width()}if(aG==null){aG=aC.find("div.tickLabel").height()}aC.remove()}}}if(aK==null){aK=0}if(aG==null){aG=0}aD.labelWidth=aK;aD.labelHeight=aG}function au(aD){var aC=aD.labelWidth,aL=aD.labelHeight,aH=aD.options.position,aF=aD.options.tickLength,aG=O.grid.axisMargin,aJ=O.grid.labelMargin,aK=aD.direction=="x"?p:aw,aE;var aB=c.grep(aK,function(aN){return aN&&aN.options.position==aH&&aN.reserveSpace});if(c.inArray(aD,aB)==aB.length-1){aG=0}if(aF==null){aF="full"}var aI=c.grep(aK,function(aN){return aN&&aN.reserveSpace});var aM=c.inArray(aD,aI)==0;if(!aM&&aF=="full"){aF=5}if(!isNaN(+aF)){aJ+=+aF}if(aD.direction=="x"){aL+=aJ;if(aH=="bottom"){q.bottom+=aL+aG;aD.box={top:I-q.bottom,height:aL}}else{aD.box={top:q.top+aG,height:aL};q.top+=aL+aG}}else{aC+=aJ;if(aH=="left"){aD.box={left:q.left+aG,width:aC};q.left+=aC+aG}else{q.right+=aC+aG;aD.box={left:G-q.right,width:aC}}}aD.position=aH;aD.tickLength=aF;aD.box.padding=aJ;aD.innermost=aM}function U(aB){if(aB.direction=="x"){aB.box.left=q.left;aB.box.width=h}else{aB.box.top=q.top;aB.box.height=w}}function t(){var aC,aE=m();c.each(aE,function(aF,aG){aG.show=aG.options.show;if(aG.show==null){aG.show=aG.used}aG.reserveSpace=aG.show||aG.options.reserveSpace;n(aG)});allocatedAxes=c.grep(aE,function(aF){return aF.reserveSpace});q.left=q.right=q.top=q.bottom=0;if(O.grid.show){c.each(allocatedAxes,function(aF,aG){S(aG);P(aG);ap(aG,aG.ticks);L(aG)});for(aC=allocatedAxes.length-1;aC>=0;--aC){au(allocatedAxes[aC])}var aD=O.grid.minBorderMargin;if(aD==null){aD=0;for(aC=0;aC<Q.length;++aC){aD=Math.max(aD,Q[aC].points.radius+Q[aC].points.lineWidth/2)}}for(var aB in q){q[aB]+=O.grid.borderWidth;q[aB]=Math.max(aD,q[aB])}}h=G-q.left-q.right;w=I-q.bottom-q.top;c.each(aE,function(aF,aG){r(aG)});if(O.grid.show){c.each(allocatedAxes,function(aF,aG){U(aG)});k()}o()}function n(aE){var aF=aE.options,aD=+(aF.min!=null?aF.min:aE.datamin),aB=+(aF.max!=null?aF.max:aE.datamax),aH=aB-aD;if(aH==0){var aC=aB==0?1:0.01;if(aF.min==null){aD-=aC}if(aF.max==null||aF.min!=null){aB+=aC}}else{var aG=aF.autoscaleMargin;if(aG!=null){if(aF.min==null){aD-=aH*aG;if(aD<0&&aE.datamin!=null&&aE.datamin>=0){aD=0}}if(aF.max==null){aB+=aH*aG;if(aB>0&&aE.datamax!=null&&aE.datamax<=0){aB=0}}}}aE.min=aD;aE.max=aB}function S(aG){var aM=aG.options;var aH;if(typeof aM.ticks=="number"&&aM.ticks>0){aH=aM.ticks}else{aH=0.3*Math.sqrt(aG.direction=="x"?G:I)}var aT=(aG.max-aG.min)/aH,aO,aB,aN,aR,aS,aQ,aI;if(aM.mode=="time"){var aJ={second:1000,minute:60*1000,hour:60*60*1000,day:24*60*60*1000,month:30*24*60*60*1000,year:365.2425*24*60*60*1000};var aK=[[1,"second"],[2,"second"],[5,"second"],[10,"second"],[30,"second"],[1,"minute"],[2,"minute"],[5,"minute"],[10,"minute"],[30,"minute"],[1,"hour"],[2,"hour"],[4,"hour"],[8,"hour"],[12,"hour"],[1,"day"],[2,"day"],[3,"day"],[0.25,"month"],[0.5,"month"],[1,"month"],[2,"month"],[3,"month"],[6,"month"],[1,"year"]];var aC=0;if(aM.minTickSize!=null){if(typeof aM.tickSize=="number"){aC=aM.tickSize}else{aC=aM.minTickSize[0]*aJ[aM.minTickSize[1]]}}for(var aS=0;aS<aK.length-1;++aS){if(aT<(aK[aS][0]*aJ[aK[aS][1]]+aK[aS+1][0]*aJ[aK[aS+1][1]])/2&&aK[aS][0]*aJ[aK[aS][1]]>=aC){break}}aO=aK[aS][0];aN=aK[aS][1];if(aN=="year"){aQ=Math.pow(10,Math.floor(Math.log(aT/aJ.year)/Math.LN10));aI=(aT/aJ.year)/aQ;if(aI<1.5){aO=1}else{if(aI<3){aO=2}else{if(aI<7.5){aO=5}else{aO=10}}}aO*=aQ}aG.tickSize=aM.tickSize||[aO,aN];aB=function(aX){var a2=[],a0=aX.tickSize[0],a3=aX.tickSize[1],a1=new Date(aX.min);var aW=a0*aJ[a3];if(a3=="second"){a1.setUTCSeconds(a(a1.getUTCSeconds(),a0))}if(a3=="minute"){a1.setUTCMinutes(a(a1.getUTCMinutes(),a0))}if(a3=="hour"){a1.setUTCHours(a(a1.getUTCHours(),a0))}if(a3=="month"){a1.setUTCMonth(a(a1.getUTCMonth(),a0))}if(a3=="year"){a1.setUTCFullYear(a(a1.getUTCFullYear(),a0))}a1.setUTCMilliseconds(0);if(aW>=aJ.minute){a1.setUTCSeconds(0)}if(aW>=aJ.hour){a1.setUTCMinutes(0)}if(aW>=aJ.day){a1.setUTCHours(0)}if(aW>=aJ.day*4){a1.setUTCDate(1)}if(aW>=aJ.year){a1.setUTCMonth(0)}var a5=0,a4=Number.NaN,aY;do{aY=a4;a4=a1.getTime();a2.push(a4);if(a3=="month"){if(a0<1){a1.setUTCDate(1);var aV=a1.getTime();a1.setUTCMonth(a1.getUTCMonth()+1);var aZ=a1.getTime();a1.setTime(a4+a5*aJ.hour+(aZ-aV)*a0);a5=a1.getUTCHours();a1.setUTCHours(0)}else{a1.setUTCMonth(a1.getUTCMonth()+a0)}}else{if(a3=="year"){a1.setUTCFullYear(a1.getUTCFullYear()+a0)}else{a1.setTime(a4+aW)}}}while(a4<aX.max&&a4!=aY);return a2};aR=function(aV,aY){var a0=new Date(aV);if(aM.timeformat!=null){return c.plot.formatDate(a0,aM.timeformat,aM.monthNames)}var aW=aY.tickSize[0]*aJ[aY.tickSize[1]];var aX=aY.max-aY.min;var aZ=(aM.twelveHourClock)?" %p":"";if(aW<aJ.minute){fmt="%h:%M:%S"+aZ}else{if(aW<aJ.day){if(aX<2*aJ.day){fmt="%h:%M"+aZ}else{fmt="%b %d %h:%M"+aZ}}else{if(aW<aJ.month){fmt="%b %d"}else{if(aW<aJ.year){if(aX<aJ.year){fmt="%b"}else{fmt="%b %y"}}else{fmt="%y"}}}}return c.plot.formatDate(a0,fmt,aM.monthNames)}}else{var aU=aM.tickDecimals;var aP=-Math.floor(Math.log(aT)/Math.LN10);if(aU!=null&&aP>aU){aP=aU}aQ=Math.pow(10,-aP);aI=aT/aQ;if(aI<1.5){aO=1}else{if(aI<3){aO=2;if(aI>2.25&&(aU==null||aP+1<=aU)){aO=2.5;++aP}}else{if(aI<7.5){aO=5}else{aO=10}}}aO*=aQ;if(aM.minTickSize!=null&&aO<aM.minTickSize){aO=aM.minTickSize}aG.tickDecimals=Math.max(0,aU!=null?aU:aP);aG.tickSize=aM.tickSize||aO;aB=function(aX){var aZ=[];var a0=a(aX.min,aX.tickSize),aW=0,aV=Number.NaN,aY;do{aY=aV;aV=a0+aW*aX.tickSize;aZ.push(aV);++aW}while(aV<aX.max&&aV!=aY);return aZ};aR=function(aV,aW){return aV.toFixed(aW.tickDecimals)}}if(aM.alignTicksWithAxis!=null){var aF=(aG.direction=="x"?p:aw)[aM.alignTicksWithAxis-1];if(aF&&aF.used&&aF!=aG){var aL=aB(aG);if(aL.length>0){if(aM.min==null){aG.min=Math.min(aG.min,aL[0])}if(aM.max==null&&aL.length>1){aG.max=Math.max(aG.max,aL[aL.length-1])}}aB=function(aX){var aY=[],aV,aW;for(aW=0;aW<aF.ticks.length;++aW){aV=(aF.ticks[aW].v-aF.min)/(aF.max-aF.min);aV=aX.min+aV*(aX.max-aX.min);aY.push(aV)}return aY};if(aG.mode!="time"&&aM.tickDecimals==null){var aE=Math.max(0,-Math.floor(Math.log(aT)/Math.LN10)+1),aD=aB(aG);if(!(aD.length>1&&/\..*0$/.test((aD[1]-aD[0]).toFixed(aE)))){aG.tickDecimals=aE}}}}aG.tickGenerator=aB;if(c.isFunction(aM.tickFormatter)){aG.tickFormatter=function(aV,aW){return""+aM.tickFormatter(aV,aW)}}else{aG.tickFormatter=aR}}function P(aF){var aH=aF.options.ticks,aG=[];if(aH==null||(typeof aH=="number"&&aH>0)){aG=aF.tickGenerator(aF)}else{if(aH){if(c.isFunction(aH)){aG=aH({min:aF.min,max:aF.max})}else{aG=aH}}}var aE,aB;aF.ticks=[];for(aE=0;aE<aG.length;++aE){var aC=null;var aD=aG[aE];if(typeof aD=="object"){aB=+aD[0];if(aD.length>1){aC=aD[1]}}else{aB=+aD}if(aC==null){aC=aF.tickFormatter(aB,aF)}if(!isNaN(aB)){aF.ticks.push({v:aB,label:aC})}}}function ap(aB,aC){if(aB.options.autoscaleMargin&&aC.length>0){if(aB.options.min==null){aB.min=Math.min(aB.min,aC[0].v)}if(aB.options.max==null&&aC.length>1){aB.max=Math.max(aB.max,aC[aC.length-1].v)}}}function W(){H.clearRect(0,0,G,I);var aC=O.grid;if(aC.show&&aC.backgroundColor){N()}if(aC.show&&!aC.aboveData){ac()}for(var aB=0;aB<Q.length;++aB){an(ak.drawSeries,[H,Q[aB]]);d(Q[aB])}an(ak.draw,[H]);if(aC.show&&aC.aboveData){ac()}}function D(aB,aI){var aE,aH,aG,aD,aF=m();for(i=0;i<aF.length;++i){aE=aF[i];if(aE.direction==aI){aD=aI+aE.n+"axis";if(!aB[aD]&&aE.n==1){aD=aI+"axis"}if(aB[aD]){aH=aB[aD].from;aG=aB[aD].to;break}}}if(!aB[aD]){aE=aI=="x"?p[0]:aw[0];aH=aB[aI+"1"];aG=aB[aI+"2"]}if(aH!=null&&aG!=null&&aH>aG){var aC=aH;aH=aG;aG=aC}return{from:aH,to:aG,axis:aE}}function N(){H.save();H.translate(q.left,q.top);H.fillStyle=am(O.grid.backgroundColor,w,0,"rgba(255, 255, 255, 0)");H.fillRect(0,0,h,w);H.restore()}function ac(){var aF;H.save();H.translate(q.left,q.top);var aH=O.grid.markings;if(aH){if(c.isFunction(aH)){var aK=aq.getAxes();aK.xmin=aK.xaxis.min;aK.xmax=aK.xaxis.max;aK.ymin=aK.yaxis.min;aK.ymax=aK.yaxis.max;aH=aH(aK)}for(aF=0;aF<aH.length;++aF){var aD=aH[aF],aC=D(aD,"x"),aI=D(aD,"y");if(aC.from==null){aC.from=aC.axis.min}if(aC.to==null){aC.to=aC.axis.max}if(aI.from==null){aI.from=aI.axis.min}if(aI.to==null){aI.to=aI.axis.max}if(aC.to<aC.axis.min||aC.from>aC.axis.max||aI.to<aI.axis.min||aI.from>aI.axis.max){continue}aC.from=Math.max(aC.from,aC.axis.min);aC.to=Math.min(aC.to,aC.axis.max);aI.from=Math.max(aI.from,aI.axis.min);aI.to=Math.min(aI.to,aI.axis.max);if(aC.from==aC.to&&aI.from==aI.to){continue}aC.from=aC.axis.p2c(aC.from);aC.to=aC.axis.p2c(aC.to);aI.from=aI.axis.p2c(aI.from);aI.to=aI.axis.p2c(aI.to);if(aC.from==aC.to||aI.from==aI.to){H.beginPath();H.strokeStyle=aD.color||O.grid.markingsColor;H.lineWidth=aD.lineWidth||O.grid.markingsLineWidth;H.moveTo(aC.from,aI.from);H.lineTo(aC.to,aI.to);H.stroke()}else{H.fillStyle=aD.color||O.grid.markingsColor;H.fillRect(aC.from,aI.to,aC.to-aC.from,aI.from-aI.to)}}}var aK=m(),aM=O.grid.borderWidth;for(var aE=0;aE<aK.length;++aE){var aB=aK[aE],aG=aB.box,aQ=aB.tickLength,aN,aL,aP,aJ;if(!aB.show||aB.ticks.length==0){continue}H.strokeStyle=aB.options.tickColor||c.color.parse(aB.options.color).scale("a",0.22).toString();H.lineWidth=1;if(aB.direction=="x"){aN=0;if(aQ=="full"){aL=(aB.position=="top"?0:w)}else{aL=aG.top-q.top+(aB.position=="top"?aG.height:0)}}else{aL=0;if(aQ=="full"){aN=(aB.position=="left"?0:h)}else{aN=aG.left-q.left+(aB.position=="left"?aG.width:0)}}if(!aB.innermost){H.beginPath();aP=aJ=0;if(aB.direction=="x"){aP=h}else{aJ=w}if(H.lineWidth==1){aN=Math.floor(aN)+0.5;aL=Math.floor(aL)+0.5}H.moveTo(aN,aL);H.lineTo(aN+aP,aL+aJ);H.stroke()}H.beginPath();for(aF=0;aF<aB.ticks.length;++aF){var aO=aB.ticks[aF].v;aP=aJ=0;if(aO<aB.min||aO>aB.max||(aQ=="full"&&aM>0&&(aO==aB.min||aO==aB.max))){continue}if(aB.direction=="x"){aN=aB.p2c(aO);aJ=aQ=="full"?-w:aQ;if(aB.position=="top"){aJ=-aJ}}else{aL=aB.p2c(aO);aP=aQ=="full"?-h:aQ;if(aB.position=="left"){aP=-aP}}if(H.lineWidth==1){if(aB.direction=="x"){aN=Math.floor(aN)+0.5}else{aL=Math.floor(aL)+0.5}}H.moveTo(aN,aL);H.lineTo(aN+aP,aL+aJ)}H.stroke()}if(aM){H.lineWidth=aM;H.strokeStyle=O.grid.borderColor;H.strokeRect(-aM/2,-aM/2,h+aM,w+aM)}H.restore()}function k(){av.find(".tickLabels").remove();var aG=['<div class="tickLabels" style="font-size:smaller">'];var aJ=m();for(var aD=0;aD<aJ.length;++aD){var aC=aJ[aD],aF=aC.box;if(!aC.show){continue}aG.push('<div class="'+aC.direction+"Axis "+aC.direction+aC.n+'Axis" style="color:'+aC.options.color+'">');for(var aE=0;aE<aC.ticks.length;++aE){var aH=aC.ticks[aE];if(!aH.label||aH.v<aC.min||aH.v>aC.max){continue}var aK={},aI;if(aC.direction=="x"){aI="center";aK.left=Math.round(q.left+aC.p2c(aH.v)-aC.labelWidth/2);if(aC.position=="bottom"){aK.top=aF.top+aF.padding}else{aK.bottom=I-(aF.top+aF.height-aF.padding)}}else{aK.top=Math.round(q.top+aC.p2c(aH.v)-aC.labelHeight/2);if(aC.position=="left"){aK.right=G-(aF.left+aF.width-aF.padding);aI="right"}else{aK.left=aF.left+aF.padding;aI="left"}}aK.width=aC.labelWidth;var aB=["position:absolute","text-align:"+aI];for(var aL in aK){aB.push(aL+":"+aK[aL]+"px")}aG.push('<div class="tickLabel" style="'+aB.join(";")+'">'+aH.label+"</div>")}aG.push("</div>")}aG.push("</div>");av.append(aG.join(""))}function d(aB){if(aB.lines.show){at(aB)}if(aB.bars.show){e(aB)}if(aB.points.show){ao(aB)}}function at(aE){function aD(aP,aQ,aI,aU,aT){var aV=aP.points,aJ=aP.pointsize,aN=null,aM=null;H.beginPath();for(var aO=aJ;aO<aV.length;aO+=aJ){var aL=aV[aO-aJ],aS=aV[aO-aJ+1],aK=aV[aO],aR=aV[aO+1];if(aL==null||aK==null){continue}if(aS<=aR&&aS<aT.min){if(aR<aT.min){continue}aL=(aT.min-aS)/(aR-aS)*(aK-aL)+aL;aS=aT.min}else{if(aR<=aS&&aR<aT.min){if(aS<aT.min){continue}aK=(aT.min-aS)/(aR-aS)*(aK-aL)+aL;aR=aT.min}}if(aS>=aR&&aS>aT.max){if(aR>aT.max){continue}aL=(aT.max-aS)/(aR-aS)*(aK-aL)+aL;aS=aT.max}else{if(aR>=aS&&aR>aT.max){if(aS>aT.max){continue}aK=(aT.max-aS)/(aR-aS)*(aK-aL)+aL;aR=aT.max}}if(aL<=aK&&aL<aU.min){if(aK<aU.min){continue}aS=(aU.min-aL)/(aK-aL)*(aR-aS)+aS;aL=aU.min}else{if(aK<=aL&&aK<aU.min){if(aL<aU.min){continue}aR=(aU.min-aL)/(aK-aL)*(aR-aS)+aS;aK=aU.min}}if(aL>=aK&&aL>aU.max){if(aK>aU.max){continue}aS=(aU.max-aL)/(aK-aL)*(aR-aS)+aS;aL=aU.max}else{if(aK>=aL&&aK>aU.max){if(aL>aU.max){continue}aR=(aU.max-aL)/(aK-aL)*(aR-aS)+aS;aK=aU.max}}if(aL!=aN||aS!=aM){H.moveTo(aU.p2c(aL)+aQ,aT.p2c(aS)+aI)}aN=aK;aM=aR;H.lineTo(aU.p2c(aK)+aQ,aT.p2c(aR)+aI)}H.stroke()}function aF(aI,aQ,aP){var aW=aI.points,aV=aI.pointsize,aN=Math.min(Math.max(0,aP.min),aP.max),aX=0,aU,aT=false,aM=1,aL=0,aR=0;while(true){if(aV>0&&aX>aW.length+aV){break}aX+=aV;var aZ=aW[aX-aV],aK=aW[aX-aV+aM],aY=aW[aX],aJ=aW[aX+aM];if(aT){if(aV>0&&aZ!=null&&aY==null){aR=aX;aV=-aV;aM=2;continue}if(aV<0&&aX==aL+aV){H.fill();aT=false;aV=-aV;aM=1;aX=aL=aR+aV;continue}}if(aZ==null||aY==null){continue}if(aZ<=aY&&aZ<aQ.min){if(aY<aQ.min){continue}aK=(aQ.min-aZ)/(aY-aZ)*(aJ-aK)+aK;aZ=aQ.min}else{if(aY<=aZ&&aY<aQ.min){if(aZ<aQ.min){continue}aJ=(aQ.min-aZ)/(aY-aZ)*(aJ-aK)+aK;aY=aQ.min}}if(aZ>=aY&&aZ>aQ.max){if(aY>aQ.max){continue}aK=(aQ.max-aZ)/(aY-aZ)*(aJ-aK)+aK;aZ=aQ.max}else{if(aY>=aZ&&aY>aQ.max){if(aZ>aQ.max){continue}aJ=(aQ.max-aZ)/(aY-aZ)*(aJ-aK)+aK;aY=aQ.max}}if(!aT){H.beginPath();H.moveTo(aQ.p2c(aZ),aP.p2c(aN));aT=true}if(aK>=aP.max&&aJ>=aP.max){H.lineTo(aQ.p2c(aZ),aP.p2c(aP.max));H.lineTo(aQ.p2c(aY),aP.p2c(aP.max));continue}else{if(aK<=aP.min&&aJ<=aP.min){H.lineTo(aQ.p2c(aZ),aP.p2c(aP.min));H.lineTo(aQ.p2c(aY),aP.p2c(aP.min));continue}}var aO=aZ,aS=aY;if(aK<=aJ&&aK<aP.min&&aJ>=aP.min){aZ=(aP.min-aK)/(aJ-aK)*(aY-aZ)+aZ;aK=aP.min}else{if(aJ<=aK&&aJ<aP.min&&aK>=aP.min){aY=(aP.min-aK)/(aJ-aK)*(aY-aZ)+aZ;aJ=aP.min}}if(aK>=aJ&&aK>aP.max&&aJ<=aP.max){aZ=(aP.max-aK)/(aJ-aK)*(aY-aZ)+aZ;aK=aP.max}else{if(aJ>=aK&&aJ>aP.max&&aK<=aP.max){aY=(aP.max-aK)/(aJ-aK)*(aY-aZ)+aZ;aJ=aP.max}}if(aZ!=aO){H.lineTo(aQ.p2c(aO),aP.p2c(aK))}H.lineTo(aQ.p2c(aZ),aP.p2c(aK));H.lineTo(aQ.p2c(aY),aP.p2c(aJ));if(aY!=aS){H.lineTo(aQ.p2c(aY),aP.p2c(aJ));H.lineTo(aQ.p2c(aS),aP.p2c(aJ))}}}H.save();H.translate(q.left,q.top);H.lineJoin="round";var aG=aE.lines.lineWidth,aB=aE.shadowSize;if(aG>0&&aB>0){H.lineWidth=aB;H.strokeStyle="rgba(0,0,0,0.1)";var aH=Math.PI/18;aD(aE.datapoints,Math.sin(aH)*(aG/2+aB/2),Math.cos(aH)*(aG/2+aB/2),aE.xaxis,aE.yaxis);H.lineWidth=aB/2;aD(aE.datapoints,Math.sin(aH)*(aG/2+aB/4),Math.cos(aH)*(aG/2+aB/4),aE.xaxis,aE.yaxis)}H.lineWidth=aG;H.strokeStyle=aE.color;var aC=ae(aE.lines,aE.color,0,w);if(aC){H.fillStyle=aC;aF(aE.datapoints,aE.xaxis,aE.yaxis)}if(aG>0){aD(aE.datapoints,0,0,aE.xaxis,aE.yaxis)}H.restore()}function ao(aE){function aH(aN,aM,aU,aK,aS,aT,aQ,aJ){var aR=aN.points,aI=aN.pointsize;for(var aL=0;aL<aR.length;aL+=aI){var aP=aR[aL],aO=aR[aL+1];if(aP==null||aP<aT.min||aP>aT.max||aO<aQ.min||aO>aQ.max){continue}H.beginPath();aP=aT.p2c(aP);aO=aQ.p2c(aO)+aK;if(aJ=="circle"){H.arc(aP,aO,aM,0,aS?Math.PI:Math.PI*2,false)}else{aJ(H,aP,aO,aM,aS)}H.closePath();if(aU){H.fillStyle=aU;H.fill()}H.stroke()}}H.save();H.translate(q.left,q.top);var aG=aE.points.lineWidth,aC=aE.shadowSize,aB=aE.points.radius,aF=aE.points.symbol;if(aG>0&&aC>0){var aD=aC/2;H.lineWidth=aD;H.strokeStyle="rgba(0,0,0,0.1)";aH(aE.datapoints,aB,null,aD+aD/2,true,aE.xaxis,aE.yaxis,aF);H.strokeStyle="rgba(0,0,0,0.2)";aH(aE.datapoints,aB,null,aD/2,true,aE.xaxis,aE.yaxis,aF)}H.lineWidth=aG;H.strokeStyle=aE.color;aH(aE.datapoints,aB,ae(aE.points,aE.color),0,false,aE.xaxis,aE.yaxis,aF);H.restore()}function E(aN,aM,aV,aI,aQ,aF,aD,aL,aK,aU,aR,aC){var aE,aT,aJ,aP,aG,aB,aO,aH,aS;if(aR){aH=aB=aO=true;aG=false;aE=aV;aT=aN;aP=aM+aI;aJ=aM+aQ;if(aT<aE){aS=aT;aT=aE;aE=aS;aG=true;aB=false}}else{aG=aB=aO=true;aH=false;aE=aN+aI;aT=aN+aQ;aJ=aV;aP=aM;if(aP<aJ){aS=aP;aP=aJ;aJ=aS;aH=true;aO=false}}if(aT<aL.min||aE>aL.max||aP<aK.min||aJ>aK.max){return}if(aE<aL.min){aE=aL.min;aG=false}if(aT>aL.max){aT=aL.max;aB=false}if(aJ<aK.min){aJ=aK.min;aH=false}if(aP>aK.max){aP=aK.max;aO=false}aE=aL.p2c(aE);aJ=aK.p2c(aJ);aT=aL.p2c(aT);aP=aK.p2c(aP);if(aD){aU.beginPath();aU.moveTo(aE,aJ);aU.lineTo(aE,aP);aU.lineTo(aT,aP);aU.lineTo(aT,aJ);aU.fillStyle=aD(aJ,aP);aU.fill()}if(aC>0&&(aG||aB||aO||aH)){aU.beginPath();aU.moveTo(aE,aJ+aF);if(aG){aU.lineTo(aE,aP+aF)}else{aU.moveTo(aE,aP+aF)}if(aO){aU.lineTo(aT,aP+aF)}else{aU.moveTo(aT,aP+aF)}if(aB){aU.lineTo(aT,aJ+aF)}else{aU.moveTo(aT,aJ+aF)}if(aH){aU.lineTo(aE,aJ+aF)}else{aU.moveTo(aE,aJ+aF)}aU.stroke()}}function e(aD){function aC(aJ,aI,aL,aG,aK,aN,aM){var aO=aJ.points,aF=aJ.pointsize;for(var aH=0;aH<aO.length;aH+=aF){if(aO[aH]==null){continue}E(aO[aH],aO[aH+1],aO[aH+2],aI,aL,aG,aK,aN,aM,H,aD.bars.horizontal,aD.bars.lineWidth)}}H.save();H.translate(q.left,q.top);H.lineWidth=aD.bars.lineWidth;H.strokeStyle=aD.color;var aB=aD.bars.align=="left"?0:-aD.bars.barWidth/2;var aE=aD.bars.fill?function(aF,aG){return ae(aD.bars,aD.color,aF,aG)}:null;aC(aD.datapoints,aB,aB+aD.bars.barWidth,0,aE,aD.xaxis,aD.yaxis);H.restore()}function ae(aD,aB,aC,aF){var aE=aD.fill;if(!aE){return null}if(aD.fillColor){return am(aD.fillColor,aC,aF,aB)}var aG=c.color.parse(aB);aG.a=typeof aE=="number"?aE:0.4;aG.normalize();return aG.toString()}function o(){av.find(".legend").remove();if(!O.legend.show){return}var aH=[],aF=false,aN=O.legend.labelFormatter,aM,aJ;for(var aE=0;aE<Q.length;++aE){aM=Q[aE];aJ=aM.label;if(!aJ){continue}if(aE%O.legend.noColumns==0){if(aF){aH.push("</tr>")}aH.push("<tr>");aF=true}if(aN){aJ=aN(aJ,aM)}aH.push('<td class="legendColorBox"><div style="border:1px solid '+O.legend.labelBoxBorderColor+';padding:1px"><div style="width:4px;height:0;border:5px solid '+aM.color+';overflow:hidden"></div></div></td><td class="legendLabel">'+aJ+"</td>")}if(aF){aH.push("</tr>")}if(aH.length==0){return}var aL='<table style="font-size:smaller;color:'+O.grid.color+'">'+aH.join("")+"</table>";if(O.legend.container!=null){c(O.legend.container).html(aL)}else{var aI="",aC=O.legend.position,aD=O.legend.margin;if(aD[0]==null){aD=[aD,aD]}if(aC.charAt(0)=="n"){aI+="top:"+(aD[1]+q.top)+"px;"}else{if(aC.charAt(0)=="s"){aI+="bottom:"+(aD[1]+q.bottom)+"px;"}}if(aC.charAt(1)=="e"){aI+="right:"+(aD[0]+q.right)+"px;"}else{if(aC.charAt(1)=="w"){aI+="left:"+(aD[0]+q.left)+"px;"}}var aK=c('<div class="legend">'+aL.replace('style="','style="position:absolute;'+aI+";")+"</div>").appendTo(av);if(O.legend.backgroundOpacity!=0){var aG=O.legend.backgroundColor;if(aG==null){aG=O.grid.backgroundColor;if(aG&&typeof aG=="string"){aG=c.color.parse(aG)}else{aG=c.color.extract(aK,"background-color")}aG.a=1;aG=aG.toString()}var aB=aK.children();c('<div style="position:absolute;width:'+aB.width()+"px;height:"+aB.height()+"px;"+aI+"background-color:"+aG+';"> </div>').prependTo(aK).css("opacity",O.legend.backgroundOpacity)}}}var ab=[],M=null;function K(aI,aG,aD){var aO=O.grid.mouseActiveRadius,a0=aO*aO+1,aY=null,aR=false,aW,aU;for(aW=Q.length-1;aW>=0;--aW){if(!aD(Q[aW])){continue}var aP=Q[aW],aH=aP.xaxis,aF=aP.yaxis,aV=aP.datapoints.points,aT=aP.datapoints.pointsize,aQ=aH.c2p(aI),aN=aF.c2p(aG),aC=aO/aH.scale,aB=aO/aF.scale;if(aH.options.inverseTransform){aC=Number.MAX_VALUE}if(aF.options.inverseTransform){aB=Number.MAX_VALUE}if(aP.lines.show||aP.points.show){for(aU=0;aU<aV.length;aU+=aT){var aK=aV[aU],aJ=aV[aU+1];if(aK==null){continue}if(aK-aQ>aC||aK-aQ<-aC||aJ-aN>aB||aJ-aN<-aB){continue}var aM=Math.abs(aH.p2c(aK)-aI),aL=Math.abs(aF.p2c(aJ)-aG),aS=aM*aM+aL*aL;if(aS<a0){a0=aS;aY=[aW,aU/aT]}}}if(aP.bars.show&&!aY){var aE=aP.bars.align=="left"?0:-aP.bars.barWidth/2,aX=aE+aP.bars.barWidth;for(aU=0;aU<aV.length;aU+=aT){var aK=aV[aU],aJ=aV[aU+1],aZ=aV[aU+2];if(aK==null){continue}if(Q[aW].bars.horizontal?(aQ<=Math.max(aZ,aK)&&aQ>=Math.min(aZ,aK)&&aN>=aJ+aE&&aN<=aJ+aX):(aQ>=aK+aE&&aQ<=aK+aX&&aN>=Math.min(aZ,aJ)&&aN<=Math.max(aZ,aJ))){aY=[aW,aU/aT]}}}}if(aY){aW=aY[0];aU=aY[1];aT=Q[aW].datapoints.pointsize;return{datapoint:Q[aW].datapoints.points.slice(aU*aT,(aU+1)*aT),dataIndex:aU,series:Q[aW],seriesIndex:aW}}return null}function aa(aB){if(O.grid.hoverable){u("plothover",aB,function(aC){return aC.hoverable!=false})}}function l(aB){if(O.grid.hoverable){u("plothover",aB,function(aC){return false})}}function R(aB){u("plotclick",aB,function(aC){return aC.clickable!=false})}function u(aC,aB,aD){var aE=y.offset(),aH=aB.pageX-aE.left-q.left,aF=aB.pageY-aE.top-q.top,aJ=C({left:aH,top:aF});aJ.pageX=aB.pageX;aJ.pageY=aB.pageY;var aK=K(aH,aF,aD);if(aK){aK.pageX=parseInt(aK.series.xaxis.p2c(aK.datapoint[0])+aE.left+q.left);aK.pageY=parseInt(aK.series.yaxis.p2c(aK.datapoint[1])+aE.top+q.top)}if(O.grid.autoHighlight){for(var aG=0;aG<ab.length;++aG){var aI=ab[aG];if(aI.auto==aC&&!(aK&&aI.series==aK.series&&aI.point[0]==aK.datapoint[0]&&aI.point[1]==aK.datapoint[1])){T(aI.series,aI.point)}}if(aK){x(aK.series,aK.datapoint,aC)}}av.trigger(aC,[aJ,aK])}function f(){if(!M){M=setTimeout(s,30)}}function s(){M=null;A.save();A.clearRect(0,0,G,I);A.translate(q.left,q.top);var aC,aB;for(aC=0;aC<ab.length;++aC){aB=ab[aC];if(aB.series.bars.show){v(aB.series,aB.point)}else{ay(aB.series,aB.point)}}A.restore();an(ak.drawOverlay,[A])}function x(aD,aB,aF){if(typeof aD=="number"){aD=Q[aD]}if(typeof aB=="number"){var aE=aD.datapoints.pointsize;aB=aD.datapoints.points.slice(aE*aB,aE*(aB+1))}var aC=al(aD,aB);if(aC==-1){ab.push({series:aD,point:aB,auto:aF});f()}else{if(!aF){ab[aC].auto=false}}}function T(aD,aB){if(aD==null&&aB==null){ab=[];f()}if(typeof aD=="number"){aD=Q[aD]}if(typeof aB=="number"){aB=aD.data[aB]}var aC=al(aD,aB);if(aC!=-1){ab.splice(aC,1);f()}}function al(aD,aE){for(var aB=0;aB<ab.length;++aB){var aC=ab[aB];if(aC.series==aD&&aC.point[0]==aE[0]&&aC.point[1]==aE[1]){return aB}}return -1}function ay(aE,aD){var aC=aD[0],aI=aD[1],aH=aE.xaxis,aG=aE.yaxis;if(aC<aH.min||aC>aH.max||aI<aG.min||aI>aG.max){return}var aF=aE.points.radius+aE.points.lineWidth/2;A.lineWidth=aF;A.strokeStyle=c.color.parse(aE.color).scale("a",0.5).toString();var aB=1.5*aF,aC=aH.p2c(aC),aI=aG.p2c(aI);A.beginPath();if(aE.points.symbol=="circle"){A.arc(aC,aI,aB,0,2*Math.PI,false)}else{aE.points.symbol(A,aC,aI,aB,false)}A.closePath();A.stroke()}function v(aE,aB){A.lineWidth=aE.bars.lineWidth;A.strokeStyle=c.color.parse(aE.color).scale("a",0.5).toString();var aD=c.color.parse(aE.color).scale("a",0.5).toString();var aC=aE.bars.align=="left"?0:-aE.bars.barWidth/2;E(aB[0],aB[1],aB[2]||0,aC,aC+aE.bars.barWidth,0,function(){return aD},aE.xaxis,aE.yaxis,A,aE.bars.horizontal,aE.bars.lineWidth)}function am(aJ,aB,aH,aC){if(typeof aJ=="string"){return aJ}else{var aI=H.createLinearGradient(0,aH,0,aB);for(var aE=0,aD=aJ.colors.length;aE<aD;++aE){var aF=aJ.colors[aE];if(typeof aF!="string"){var aG=c.color.parse(aC);if(aF.brightness!=null){aG=aG.scale("rgb",aF.brightness)}if(aF.opacity!=null){aG.a*=aF.opacity}aF=aG.toString()}aI.addColorStop(aE/(aD-1),aF)}return aI}}}c.plot=function(g,e,d){var f=new b(c(g),e,d,c.plot.plugins);return f};c.plot.version="0.7";c.plot.plugins=[];c.plot.formatDate=function(l,f,h){var o=function(d){d=""+d;return d.length==1?"0"+d:d};var e=[];var p=false,j=false;var n=l.getUTCHours();var k=n<12;if(h==null){h=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]}if(f.search(/%p|%P/)!=-1){if(n>12){n=n-12}else{if(n==0){n=12}}}for(var g=0;g<f.length;++g){var m=f.charAt(g);if(p){switch(m){case"h":m=""+n;break;case"H":m=o(n);break;case"M":m=o(l.getUTCMinutes());break;case"S":m=o(l.getUTCSeconds());break;case"d":m=""+l.getUTCDate();break;case"m":m=""+(l.getUTCMonth()+1);break;case"y":m=""+l.getUTCFullYear();break;case"b":m=""+h[l.getUTCMonth()];break;case"p":m=(k)?("am"):("pm");break;case"P":m=(k)?("AM"):("PM");break;case"0":m="";j=true;break}if(m&&j){m=o(m);j=false}e.push(m);if(!j){p=false}}else{if(m=="%"){p=true}else{e.push(m)}}}return e.join("")};function a(e,d){return d*Math.floor(e/d)}})(jQuery);
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.flot.navigate.min.js'
--- dashboard_app/static/dashboard_app/js/jquery.flot.navigate.min.js	2011-05-05 00:39:20 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.flot.navigate.min.js	1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-(function(i){i.fn.drag=function(j,k,l){if(k){this.bind("dragstart",j)}if(l){this.bind("dragend",l)}return !j?this.trigger("drag"):this.bind("drag",k?k:j)};var d=i.event,c=d.special,h=c.drag={not:":input",distance:0,which:1,dragging:false,setup:function(j){j=i.extend({distance:h.distance,which:h.which,not:h.not},j||{});j.distance=e(j.distance);d.add(this,"mousedown",f,j);if(this.attachEvent){this.attachEvent("ondragstart",a)}},teardown:function(){d.remove(this,"mousedown",f);if(this===h.dragging){h.dragging=h.proxy=false}g(this,true);if(this.detachEvent){this.detachEvent("ondragstart",a)}}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}};function f(j){var k=this,l,m=j.data||{};if(m.elem){k=j.dragTarget=m.elem;j.dragProxy=h.proxy||k;j.cursorOffsetX=m.pageX-m.left;j.cursorOffsetY=m.pageY-m.top;j.offsetX=j.pageX-j.cursorOffsetX;j.offsetY=j.pageY-j.cursorOffsetY}else{if(h.dragging||(m.which>0&&j.which!=m.which)||i(j.target).is(m.not)){return}}switch(j.type){case"mousedown":i.extend(m,i(k).offset(),{elem:k,target:j.target,pageX:j.pageX,pageY:j.pageY});d.add(document,"mousemove mouseup",f,m);g(k,false);h.dragging=null;return false;case !h.dragging&&"mousemove":if(e(j.pageX-m.pageX)+e(j.pageY-m.pageY)<m.distance){break}j.target=m.target;l=b(j,"dragstart",k);if(l!==false){h.dragging=k;h.proxy=j.dragProxy=i(l||k)[0]}case"mousemove":if(h.dragging){l=b(j,"drag",k);if(c.drop){c.drop.allowed=(l!==false);c.drop.handler(j)}if(l!==false){break}j.type="mouseup"}case"mouseup":d.remove(document,"mousemove mouseup",f);if(h.dragging){if(c.drop){c.drop.handler(j)}b(j,"dragend",k)}g(k,true);h.dragging=h.proxy=m.elem=false;break}return true}function b(m,k,j){m.type=k;var l=i.event.handle.call(j,m);return l===false?false:l||m.result}function e(j){return Math.pow(j,2)}function a(){return(h.dragging===false)}function g(j,k){if(!j){return}j.unselectable=k?"off":"on";j.onselectstart=function(){return k};if(j.style){j.style.MozUserSelect=k?"":"none"}}})(jQuery);(function(f){var e=["DOMMouseScroll","mousewheel"];f.event.special.mousewheel={setup:function(){if(this.addEventListener){for(var a=e.length;a;){this.addEventListener(e[--a],d,false)}}else{this.onmousewheel=d}},teardown:function(){if(this.removeEventListener){for(var a=e.length;a;){this.removeEventListener(e[--a],d,false)}}else{this.onmousewheel=null}}};f.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}});function d(b){var h=[].slice.call(arguments,1),a=0,c=true;b=f.event.fix(b||window.event);b.type="mousewheel";if(b.wheelDelta){a=b.wheelDelta/120}if(b.detail){a=-b.detail/3}h.unshift(b,a);return f.event.handle.apply(this,h)}})(jQuery);(function(b){var a={xaxis:{zoomRange:null,panRange:null},zoom:{interactive:false,trigger:"dblclick",amount:1.5},pan:{interactive:false,cursor:"move",frameRate:20}};function c(o){function m(q,p){var r=o.offset();r.left=q.pageX-r.left;r.top=q.pageY-r.top;if(p){o.zoomOut({center:r})}else{o.zoom({center:r})}}function d(p,q){m(p,q<0);return false}var i="default",g=0,e=0,n=null;function f(p){if(p.which!=1){return false}var q=o.getPlaceholder().css("cursor");if(q){i=q}o.getPlaceholder().css("cursor",o.getOptions().pan.cursor);g=p.pageX;e=p.pageY}function j(q){var p=o.getOptions().pan.frameRate;if(n||!p){return}n=setTimeout(function(){o.pan({left:g-q.pageX,top:e-q.pageY});g=q.pageX;e=q.pageY;n=null},1/p*1000)}function h(p){if(n){clearTimeout(n);n=null}o.getPlaceholder().css("cursor",i);o.pan({left:g-p.pageX,top:e-p.pageY})}function l(q,p){var r=q.getOptions();if(r.zoom.interactive){p[r.zoom.trigger](m);p.mousewheel(d)}if(r.pan.interactive){p.bind("dragstart",{distance:10},f);p.bind("drag",j);p.bind("dragend",h)}}o.zoomOut=function(p){if(!p){p={}}if(!p.amount){p.amount=o.getOptions().zoom.amount}p.amount=1/p.amount;o.zoom(p)};o.zoom=function(q){if(!q){q={}}var x=q.center,r=q.amount||o.getOptions().zoom.amount,p=o.width(),t=o.height();if(!x){x={left:p/2,top:t/2}}var s=x.left/p,v=x.top/t,u={x:{min:x.left-s*p/r,max:x.left+(1-s)*p/r},y:{min:x.top-v*t/r,max:x.top+(1-v)*t/r}};b.each(o.getAxes(),function(z,C){var D=C.options,B=u[C.direction].min,w=u[C.direction].max,E=D.zoomRange;if(E===false){return}B=C.c2p(B);w=C.c2p(w);if(B>w){var A=B;B=w;w=A}var y=w-B;if(E&&((E[0]!=null&&y<E[0])||(E[1]!=null&&y>E[1]))){return}D.min=B;D.max=w});o.setupGrid();o.draw();if(!q.preventEvent){o.getPlaceholder().trigger("plotzoom",[o])}};o.pan=function(p){var q={x:+p.left,y:+p.top};if(isNaN(q.x)){q.x=0}if(isNaN(q.y)){q.y=0}b.each(o.getAxes(),function(s,u){var v=u.options,t,r,w=q[u.direction];t=u.c2p(u.p2c(u.min)+w),r=u.c2p(u.p2c(u.max)+w);var x=v.panRange;if(x===false){return}if(x){if(x[0]!=null&&x[0]>t){w=x[0]-t;t+=w;r+=w}if(x[1]!=null&&x[1]<r){w=x[1]-r;t+=w;r+=w}}v.min=t;v.max=r});o.setupGrid();o.draw();if(!p.preventEvent){o.getPlaceholder().trigger("plotpan",[o])}};function k(q,p){p.unbind(q.getOptions().zoom.trigger,m);p.unbind("mousewheel",d);p.unbind("dragstart",f);p.unbind("drag",j);p.unbind("dragend",h);if(n){clearTimeout(n)}}o.hooks.bindEvents.push(l);o.hooks.shutdown.push(k)}b.plot.plugins.push({init:c,options:a,name:"navigate",version:"1.3"})})(jQuery);
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.flot.selection.min.js'
--- dashboard_app/static/dashboard_app/js/jquery.flot.selection.min.js	2011-05-05 00:39:20 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.flot.selection.min.js	1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-(function(a){function b(k){var p={first:{x:-1,y:-1},second:{x:-1,y:-1},show:false,active:false};var m={};var r=null;function e(s){if(p.active){l(s);k.getPlaceholder().trigger("plotselecting",[g()])}}function n(s){if(s.which!=1){return}document.body.focus();if(document.onselectstart!==undefined&&m.onselectstart==null){m.onselectstart=document.onselectstart;document.onselectstart=function(){return false}}if(document.ondrag!==undefined&&m.ondrag==null){m.ondrag=document.ondrag;document.ondrag=function(){return false}}d(p.first,s);p.active=true;r=function(t){j(t)};a(document).one("mouseup",r)}function j(s){r=null;if(document.onselectstart!==undefined){document.onselectstart=m.onselectstart}if(document.ondrag!==undefined){document.ondrag=m.ondrag}p.active=false;l(s);if(f()){i()}else{k.getPlaceholder().trigger("plotunselected",[]);k.getPlaceholder().trigger("plotselecting",[null])}return false}function g(){if(!f()){return null}var u={},t=p.first,s=p.second;a.each(k.getAxes(),function(v,w){if(w.used){var y=w.c2p(t[w.direction]),x=w.c2p(s[w.direction]);u[v]={from:Math.min(y,x),to:Math.max(y,x)}}});return u}function i(){var s=g();k.getPlaceholder().trigger("plotselected",[s]);if(s.xaxis&&s.yaxis){k.getPlaceholder().trigger("selected",[{x1:s.xaxis.from,y1:s.yaxis.from,x2:s.xaxis.to,y2:s.yaxis.to}])}}function h(t,u,s){return u<t?t:(u>s?s:u)}function d(w,t){var v=k.getOptions();var u=k.getPlaceholder().offset();var s=k.getPlotOffset();w.x=h(0,t.pageX-u.left-s.left,k.width());w.y=h(0,t.pageY-u.top-s.top,k.height());if(v.selection.mode=="y"){w.x=w==p.first?0:k.width()}if(v.selection.mode=="x"){w.y=w==p.first?0:k.height()}}function l(s){if(s.pageX==null){return}d(p.second,s);if(f()){p.show=true;k.triggerRedrawOverlay()}else{q(true)}}function q(s){if(p.show){p.show=false;k.triggerRedrawOverlay();if(!s){k.getPlaceholder().trigger("plotunselected",[])}}}function c(s,w){var t,y,z,A,x=k.getAxes();for(var u in x){t=x[u];if(t.direction==w){A=w+t.n+"axis";if(!s[A]&&t.n==1){A=w+"axis"}if(s[A]){y=s[A].from;z=s[A].to;break}}}if(!s[A]){t=w=="x"?k.getXAxes()[0]:k.getYAxes()[0];y=s[w+"1"];z=s[w+"2"]}if(y!=null&&z!=null&&y>z){var v=y;y=z;z=v}return{from:y,to:z,axis:t}}function o(t,s){var v,u,w=k.getOptions();if(w.selection.mode=="y"){p.first.x=0;p.second.x=k.width()}else{u=c(t,"x");p.first.x=u.axis.p2c(u.from);p.second.x=u.axis.p2c(u.to)}if(w.selection.mode=="x"){p.first.y=0;p.second.y=k.height()}else{u=c(t,"y");p.first.y=u.axis.p2c(u.from);p.second.y=u.axis.p2c(u.to)}p.show=true;k.triggerRedrawOverlay();if(!s&&f()){i()}}function f(){var s=5;return Math.abs(p.second.x-p.first.x)>=s&&Math.abs(p.second.y-p.first.y)>=s}k.clearSelection=q;k.setSelection=o;k.getSelection=g;k.hooks.bindEvents.push(function(t,s){var u=t.getOptions();if(u.selection.mode!=null){s.mousemove(e);s.mousedown(n)}});k.hooks.drawOverlay.push(function(v,D){if(p.show&&f()){var t=v.getPlotOffset();var s=v.getOptions();D.save();D.translate(t.left,t.top);var z=a.color.parse(s.selection.color);D.strokeStyle=z.scale("a",0.8).toString();D.lineWidth=1;D.lineJoin="round";D.fillStyle=z.scale("a",0.4).toString();var B=Math.min(p.first.x,p.second.x),A=Math.min(p.first.y,p.second.y),C=Math.abs(p.second.x-p.first.x),u=Math.abs(p.second.y-p.first.y);D.fillRect(B,A,C,u);D.strokeRect(B,A,C,u);D.restore()}});k.hooks.shutdown.push(function(t,s){s.unbind("mousemove",e);s.unbind("mousedown",n);if(r){a(document).unbind("mouseup",r)}})}a.plot.plugins.push({init:b,options:{selection:{mode:null,color:"#e8cfac"}},name:"selection",version:"1.1"})})(jQuery);
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.flot.stack.min.js'
--- dashboard_app/static/dashboard_app/js/jquery.flot.stack.min.js	2011-08-18 15:42:39 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.flot.stack.min.js	1970-01-01 00:00:00 +0000
@@ -1,1 +0,0 @@
-(function(b){var a={series:{stack:null}};function c(f){function d(k,j){var h=null;for(var g=0;g<j.length;++g){if(k==j[g]){break}if(j[g].stack==k.stack){h=j[g]}}return h}function e(C,v,g){if(v.stack==null){return}var p=d(v,C.getData());if(!p){return}var z=g.pointsize,F=g.points,h=p.datapoints.pointsize,y=p.datapoints.points,t=[],x,w,k,J,I,r,u=v.lines.show,G=v.bars.horizontal,o=z>2&&(G?g.format[2].x:g.format[2].y),n=u&&v.lines.steps,E=true,q=G?1:0,H=G?0:1,D=0,B=0,A;while(true){if(D>=F.length){break}A=t.length;if(F[D]==null){for(m=0;m<z;++m){t.push(F[D+m])}D+=z}else{if(B>=y.length){if(!u){for(m=0;m<z;++m){t.push(F[D+m])}}D+=z}else{if(y[B]==null){for(m=0;m<z;++m){t.push(null)}E=true;B+=h}else{x=F[D+q];w=F[D+H];J=y[B+q];I=y[B+H];r=0;if(x==J){for(m=0;m<z;++m){t.push(F[D+m])}t[A+H]+=I;r=I;D+=z;B+=h}else{if(x>J){if(u&&D>0&&F[D-z]!=null){k=w+(F[D-z+H]-w)*(J-x)/(F[D-z+q]-x);t.push(J);t.push(k+I);for(m=2;m<z;++m){t.push(F[D+m])}r=I}B+=h}else{if(E&&u){D+=z;continue}for(m=0;m<z;++m){t.push(F[D+m])}if(u&&B>0&&y[B-h]!=null){r=I+(y[B-h+H]-I)*(x-J)/(y[B-h+q]-J)}t[A+H]+=r;D+=z}}E=false;if(A!=t.length&&o){t[A+2]+=r}}}}if(n&&A!=t.length&&A>0&&t[A]!=null&&t[A]!=t[A-z]&&t[A+1]!=t[A-z+1]){for(m=0;m<z;++m){t[A+z+m]=t[A+m]}t[A+1]=t[A-z+1]}}g.points=t}f.hooks.processDatapoints.push(e)}b.plot.plugins.push({init:c,options:a,name:"stack",version:"1.2"})})(jQuery);
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.formset.js'
--- dashboard_app/static/dashboard_app/js/jquery.formset.js	2012-09-19 04:02:42 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.formset.js	1970-01-01 00:00:00 +0000
@@ -1,209 +0,0 @@
-/**
- * jQuery Formset 1.3-pre
- * @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
- * @requires jQuery 1.2.6 or later
- *
- * Copyright (c) 2009, Stanislaus Madueke
- * All rights reserved.
- *
- * Licensed under the New BSD License
- * See: http://www.opensource.org/licenses/bsd-license.php
- */
-;(function($) {
-    $.fn.formset = function(opts)
-    {
-        var options = $.extend({}, $.fn.formset.defaults, opts),
-            flatExtraClasses = options.extraClasses.join(' '),
-            totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS'),
-            maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS'),
-            childElementSelector = 'input,select,textarea,label,div',
-            $$ = $(this),
-
-            applyExtraClasses = function(row, ndx) {
-                if (options.extraClasses) {
-                    row.removeClass(flatExtraClasses);
-                    row.addClass(options.extraClasses[ndx % options.extraClasses.length]);
-                }
-            },
-
-            updateElementIndex = function(elem, prefix, ndx) {
-                var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
-                    replacement = prefix + '-' + ndx + '-';
-                if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
-                if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
-                if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
-            },
-
-            hasChildElements = function(row) {
-                return row.find(childElementSelector).length > 0;
-            },
-
-            showAddButton = function() {
-                return maxForms.length == 0 ||   // For Django versions pre 1.2
-                    (maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0))
-            },
-
-            insertDeleteLink = function(row) {
-                if (row.is('TR')) {
-                    // If the forms are laid out in table rows, insert
-                    // the remove button into the last table cell:
-                    row.children(':last').append('<a class="' + options.deleteCssClass +'" href="javascript:void(0)">' + options.deleteText + '</a>');
-                } else if (row.is('UL') || row.is('OL')) {
-                    // If they're laid out as an ordered/unordered list,
-                    // insert an <li> after the last list item:
-                    row.append('<li><a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a></li>');
-                } else {
-                    // Otherwise, just insert the remove button as the
-                    // last child element of the form's container:
-                    row.append('<a class="' + options.deleteCssClass + '" href="javascript:void(0)">' + options.deleteText +'</a>');
-                }
-                row.find('a.' + options.deleteCssClass).click(function() {
-                    var row = $(this).parents('.' + options.formCssClass),
-                        del = row.find('input:hidden[id $= "-DELETE"]'),
-                        buttonRow = row.siblings("a." + options.addCssClass + ', .' + options.formCssClass + '-add'),
-                        forms;
-                    if (del.length) {
-                        // We're dealing with an inline formset.
-                        // Rather than remove this form from the DOM, we'll mark it as deleted
-                        // and hide it, then let Django handle the deleting:
-                        del.val('on');
-                        row.hide();
-                        forms = $('.' + options.formCssClass).not(':hidden');
-                    } else {
-                        row.remove();
-                        // Update the TOTAL_FORMS count:
-                        forms = $('.' + options.formCssClass).not('.formset-custom-template');
-                        totalForms.val(forms.length);
-                    }
-                    for (var i=0, formCount=forms.length; i<formCount; i++) {
-                        // Apply `extraClasses` to form rows so they're nicely alternating:
-                        applyExtraClasses(forms.eq(i), i);
-                        if (!del.length) {
-                            // Also update names and IDs for all child controls (if this isn't
-                            // a delete-able inline formset) so they remain in sequence:
-                            forms.eq(i).find(childElementSelector).each(function() {
-                                updateElementIndex($(this), options.prefix, i);
-                            });
-                        }
-                    }
-                    // Check if we need to show the add button:
-                    if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show();
-                    // If a post-delete callback was provided, call it with the deleted form:
-                    if (options.removed) options.removed(row);
-                    return false;
-                });
-            };
-
-        $$.each(function(i) {
-            var row = $(this),
-                del = row.find('input:checkbox[id $= "-DELETE"]');
-            if (del.length) {
-                // If you specify "can_delete = True" when creating an inline formset,
-                // Django adds a checkbox to each form in the formset.
-                // Replace the default checkbox with a hidden field:
-                if (del.is(':checked')) {
-                    // If an inline formset containing deleted forms fails validation, make sure
-                    // we keep the forms hidden (thanks for the bug report and suggested fix Mike)
-                    del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" value="on" />');
-                    row.hide();
-                } else {
-                    del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');
-                }
-                // Hide any labels associated with the DELETE checkbox:
-                $('label[for="' + del.attr('id') + '"]').hide();
-                del.remove();
-            }
-            if (hasChildElements(row)) {
-                row.addClass(options.formCssClass);
-// XXX mwhudson 2012-09-13: not sure what this check is for, doesn't
-// work well when whole form is hidden though...
-//                if (row.is(':visible')) {
-                    insertDeleteLink(row);
-                    applyExtraClasses(row, i);
-//                }
-            }
-        });
-
-        if ($$.length) {
-            var hideAddButton = !showAddButton(),
-                addButton, template;
-            if (options.formTemplate) {
-                // If a form template was specified, we'll clone it to generate new form instances:
-                template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
-                template.removeAttr('id').addClass(options.formCssClass + ' formset-custom-template');
-                template.find(childElementSelector).each(function() {
-                    updateElementIndex($(this), options.prefix, '__prefix__');
-                });
-                insertDeleteLink(template);
-            } else {
-                // Otherwise, use the last form in the formset; this works much better if you've got
-                // extra (>= 1) forms (thnaks to justhamade for pointing this out):
-                template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
-                template.find('input:hidden[id $= "-DELETE"]').remove();
-                // Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
-                template.find(childElementSelector).not(options.keepFieldValues).each(function() {
-                    var elem = $(this);
-                    // If this is a checkbox or radiobutton, uncheck it.
-                    // This fixes Issue 1, reported by Wilson.Andrew.J:
-                    if (elem.is('input:checkbox') || elem.is('input:radio')) {
-                        elem.attr('checked', false);
-                    } else {
-                        elem.val('');
-                    }
-                });
-            }
-            // FIXME: Perhaps using $.data would be a better idea?
-            options.formTemplate = template;
-            $$.data('options', options);
-
-            if ($$.attr('tagName') == 'TR') {
-                // If forms are laid out as table rows, insert the
-                // "add" button in a new table row:
-                var numCols = $$.eq(0).children().length,   // This is a bit of an assumption :|
-                    buttonRow = $('<tr><td colspan="' + numCols + '"><a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a></tr>')
-                                .addClass(options.formCssClass + '-add');
-                $$.parent().append(buttonRow);
-                if (hideAddButton) buttonRow.hide();
-                addButton = buttonRow.find('a');
-            } else {
-                // Otherwise, insert it immediately after the last form:
-                $$.filter(':last').after('<a class="' + options.addCssClass + '" href="javascript:void(0)">' + options.addText + '</a>');
-                addButton = $$.filter(':last').next();
-                if (hideAddButton) addButton.hide();
-            }
-            addButton.click(function() {
-                var formCount = parseInt(totalForms.val()),
-                    row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
-                    buttonRow = $($(this).parents('tr.' + options.formCssClass + '-add').get(0) || this);
-                applyExtraClasses(row, formCount);
-                row.insertBefore(buttonRow).show();
-                row.find(childElementSelector).each(function() {
-                    updateElementIndex($(this), options.prefix, formCount);
-                });
-                totalForms.val(formCount + 1);
-                // Check if we've exceeded the maximum allowed number of forms:
-                if (!showAddButton()) buttonRow.hide();
-                // If a post-add callback was supplied, call it with the added form:
-                if (options.added) options.added(row);
-                return false;
-            });
-        }
-
-        return $$;
-    }
-
-    /* Setup plugin defaults */
-    $.fn.formset.defaults = {
-        prefix: 'form',                  // The form prefix for your django formset
-        formTemplate: null,              // The jQuery selection cloned to generate new form instances
-        addText: 'add another',          // Text for the add link
-        deleteText: 'remove',            // Text for the delete link
-        addCssClass: 'add-row',          // CSS class applied to the add link
-        deleteCssClass: 'delete-row',    // CSS class applied to the delete link
-        formCssClass: 'dynamic-form',    // CSS class applied to each form in a formset
-        extraClasses: [],                // Additional CSS classes, which will be applied to each form in turn
-        keepFieldValues: '',             // jQuery selector for fields whose values should be kept when the form is cloned
-        added: null,                     // Function called each time a new form is added
-        removed: null                    // Function called each time a form is deleted
-    };
-})(jQuery)

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.rpc.js'
--- dashboard_app/static/dashboard_app/js/jquery.rpc.js	2011-05-03 20:08:05 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.rpc.js	1970-01-01 00:00:00 +0000
@@ -1,200 +0,0 @@
-function parseISO8601(str) {
-    // See http://www.xmlrpc.com/spec for reference
-    // Format is YYYY MM DD 'T' HH ':' MM ':' SS
-    // Example: 19980717T14:08:55
-    //          1998-Jun-17 14:08:55
-    //console.log("Parsing ISO8601 date:", str)
-
-    var parts = str.split("T");
-    var date_part = parts[0];
-    var time_parts = parts[1].split(":");
-
-    var date = new Date;
-    date.setUTCFullYear(Number(date_part.substring(0, 4)));
-    date.setUTCMonth(Number(date_part.substring(4, 6) - 1));
-    date.setUTCDate(Number(date_part.substring(6, 8)));
-    date.setUTCHours(Number(time_parts[0]));
-    date.setUTCMinutes(Number(time_parts[1]));
-    date.setUTCSeconds(Number(time_parts[2]));
-
-    //console.log("Final date:", date);
-    return date;
-} 
-
-jQuery.rpc = function(url, dataType, onLoadCallback, version) {
-    return new (function(url, dataType, onLoadCallback, version) {
-        version = version || "1.0";
-        dataType = dataType || "json";
-        if(dataType != "json" && dataType != "xml") {
-            new Error("IllegalArgument: Unsupported data type");
-        }
-        var _self = this;
-        var serializeToXml = function(data) {
-            switch (typeof data) {
-            case 'boolean':
-                return '<boolean>'+ ((data) ? '1' : '0') +'</boolean>';
-            case 'number':
-                var parsed = parseInt(data);
-                if(parsed == data) {
-                    return '<int>'+ data +'</int>';
-                }
-                return '<double>'+ data +'</double>';
-            case 'string':
-                return '<string>'+ data +'</string>';
-            case 'object':
-                if(data instanceof Date) {
-                    return '<dateTime.iso8601>'+ data.getFullYear() + data.getMonth() + data.getDate() +'T'+ data.getHours() +':'+ data.getMinutes() +':'+ data.getSeconds() +'</dateTime.iso8601>';
-                } else if(data instanceof Array) {
-                    var ret = '<array><data>'+"\n";
-                    for (var i=0; i < data.length; i++) {
-                        ret += '  <value>'+ serializeToXml(data[i]) +"</value>\n";
-                    }
-                    ret += '</data></array>';
-                    return ret;
-                } else {
-                    var ret = '<struct>'+"\n";
-                    jQuery.each(data, function(key, value) {
-                        ret += "  <member><name>"+ key +"</name><value>";
-                        ret += serializeToXml(value) +"</value></member>\n";
-                    });
-                    ret += '</struct>';
-                    return ret;
-                }
-            }
-        }
-        var xmlRpc = function(method, params) {
-            var ret = '<?xml version="'+version+'"?><methodCall><methodName>'+method+'</methodName><params>';
-            for(var i=0; i<params.length; i++) {
-                ret += "<param><value>"+serializeToXml(params[i])+"</value></param>";
-            }
-            ret += "</params></methodCall>";
-            return ret;
-        }
-        var parseXmlValue = function(node) {
-            childs = jQuery(node).children();
-            for(var i=0; i < childs.length; i++) {
-                switch(childs[i].tagName) {
-                case 'boolean':
-                    return (jQuery(childs[i]).text() == 1);
-                case 'int':
-                    return parseInt(jQuery(childs[i]).text());
-                case 'double':
-                    return parseFloat(jQuery(childs[i]).text());
-                case "string":
-                    return jQuery(childs[i]).text();
-                case "array":
-                    var ret = [];
-                    jQuery("> data > value", childs[i]).each(
-                        function() {
-                            ret.push(parseXmlValue(this));
-                        }
-                    );
-                    return ret;
-                case "struct":
-                    var ret = {};
-                    jQuery("> member", childs[i]).each(
-                        function() {
-                            ret[jQuery( "> name", this).text()] = parseXmlValue(jQuery("value", this));
-                        }
-                    );
-                    return ret;
-                case "dateTime.iso8601":
-                    return parseISO8601($(childs[i]).text());
-                }
-            }
-        }
-        var parseXmlResponse = function(data) {
-            var ret = {};
-            ret.version = version;
-            jQuery("methodResponse params param > value", data).each(
-                function(index) {
-                    ret.result = parseXmlValue(this);
-                }
-            );
-            jQuery("methodResponse fault > value", data).each(
-                function(index) {
-                    ret.error = parseXmlValue(this);
-                }
-            );
-            return ret;
-        }
-        var rpc_contents = {
-            'xml':'text/xml'
-            ,'json':'application/json'
-        };
-        var _rpc = function(method, callback) {
-            var params = [];
-            for (var i=2; i<arguments.length; i++) {
-                params.push(arguments[i]);
-            }
-            // console.log(params);
-            var data;
-            if(dataType == 'json') {
-                data = {
-                    "version": version,
-                    "method": method,
-                    "params": params
-                };
-            } else {
-                data = xmlRpc(method, params);
-            }
-            jQuery.ajax({
-                "url": url,
-                "dataType": dataType,
-                "type": "POST",
-                "data": data,
-                "success": function(inp) {
-                    var json = inp;
-                    if(dataType == "xml") {
-                        json = parseXmlResponse(inp);
-                    }
-                    //console.log("JSON response:", json);
-                    callback(json);
-                },
-                "error": function(jqXHR, textStatus, errorThrown) {
-                    $.error("AJAX error in RPC call: "+textStatus);
-                },
-                "processData": false,
-                "contentType": rpc_contents[dataType]
-            });
-        };
-        _rpc("system.listMethods", 
-            function(json) {
-                //console.log(json);
-                /* get the functions */
-                if(!json.result) {
-                    return;
-                }
-                var proc = null;
-                for(var i = 0; i<json.result.length; i++) {
-                    proc = json.result[i];
-                    var obj = _self;
-                    var objStack = proc.split(/\./);
-                    for(var j = 0; j < (objStack.length - 1); j++){
-                        obj[objStack[j]] = obj[objStack[j]] || {};
-                        obj = obj[objStack[j]];
-                    }
-                    /* add the new procedure */
-                    obj[objStack[j]] = (
-                        function(method, obj) {
-                            var _outer = {"method":method,"rpc":_rpc};
-                            return function(callback) {
-                                var params = [];
-                                params.push(_outer.method);
-                                params.push(callback);
-                                for (var i=1; i<arguments.length; i++) {
-                                    params.push(arguments[i]);
-                                }
-                                _rpc.apply(_self, params);
-                            }
-                        }
-                        )(proc, _rpc);
-                }
-                //console.log('Load was performed.');
-                if(onLoadCallback) {
-                    onLoadCallback(_self);
-                }
-            }
-        );
-    })(url, dataType, onLoadCallback, version);
-};

=== removed file 'dashboard_app/static/dashboard_app/js/jquery.tooltip.min.js'
--- dashboard_app/static/dashboard_app/js/jquery.tooltip.min.js	2013-06-10 15:33:53 +0000
+++ dashboard_app/static/dashboard_app/js/jquery.tooltip.min.js	1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
-/*
- * jQuery Tooltip plugin 1.3
- *
- * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/
- * http://docs.jquery.com/Plugins/Tooltip
- *
- * Copyright (c) 2006 - 2008 Jörn Zaefferer
- *
- * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $
- * 
- * Dual licensed under the MIT and GPL licenses:
- *   http://www.opensource.org/licenses/mit-license.php
- *   http://www.gnu.org/licenses/gpl.html
- */;(function($){var helper={},current,title,tID,IE=$.browser.msie&&/MSIE\s(5\.5|6\.)/.test(navigator.userAgent),track=false;$.tooltip={blocked:false,defaults:{delay:200,fade:false,showURL:true,extraClass:"",top:15,left:15,id:"tooltip"},block:function(){$.tooltip.blocked=!$.tooltip.blocked;}};$.fn.extend({tooltip:function(settings){settings=$.extend({},$.tooltip.defaults,settings);createHelper(settings);return this.each(function(){$.data(this,"tooltip",settings);this.tOpacity=helper.parent.css("opacity");this.tooltipText=this.title;$(this).removeAttr("title");this.alt="";}).mouseover(save).mouseout(hide).click(hide);},fixPNG:IE?function(){return this.each(function(){var image=$(this).css('backgroundImage');if(image.match(/^url\(["']?(.*\.png)["']?\)$/i)){image=RegExp.$1;$(this).css({'backgroundImage':'none','filter':"progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='"+image+"')"}).each(function(){var position=$(this).css('position');if(position!='absolute'&&position!='relative')$(this).css('position','relative');});}});}:function(){return this;},unfixPNG:IE?function(){return this.each(function(){$(this).css({'filter':'',backgroundImage:''});});}:function(){return this;},hideWhenEmpty:function(){return this.each(function(){$(this)[$(this).html()?"show":"hide"]();});},url:function(){return this.attr('href')||this.attr('src');}});function createHelper(settings){if(helper.parent)return;helper.parent=$('<div id="'+settings.id+'"><h3></h3><div class="body"></div><div class="url"></div></div>').appendTo(document.body).hide();if($.fn.bgiframe)helper.parent.bgiframe();helper.title=$('h3',helper.parent);helper.body=$('div.body',helper.parent);helper.url=$('div.url',helper.parent);}function settings(element){return $.data(element,"tooltip");}function handle(event){if(settings(this).delay)tID=setTimeout(show,settings(this).delay);else
-show();track=!!settings(this).track;$(document.body).bind('mousemove',update);update(event);}function save(){if($.tooltip.blocked||this==current||(!this.tooltipText&&!settings(this).bodyHandler))return;current=this;title=this.tooltipText;if(settings(this).bodyHandler){helper.title.hide();var bodyContent=settings(this).bodyHandler.call(this);if(bodyContent.nodeType||bodyContent.jquery){helper.body.empty().append(bodyContent)}else{helper.body.html(bodyContent);}helper.body.show();}else if(settings(this).showBody){var parts=title.split(settings(this).showBody);helper.title.html(parts.shift()).show();helper.body.empty();for(var i=0,part;(part=parts[i]);i++){if(i>0)helper.body.append("<br/>");helper.body.append(part);}helper.body.hideWhenEmpty();}else{helper.title.html(title).show();helper.body.hide();}if(settings(this).showURL&&$(this).url())helper.url.html($(this).url().replace('http://','')).show();else
-helper.url.hide();helper.parent.addClass(settings(this).extraClass);if(settings(this).fixPNG)helper.parent.fixPNG();handle.apply(this,arguments);}function show(){tID=null;if((!IE||!$.fn.bgiframe)&&settings(current).fade){if(helper.parent.is(":animated"))helper.parent.stop().show().fadeTo(settings(current).fade,current.tOpacity);else
-helper.parent.is(':visible')?helper.parent.fadeTo(settings(current).fade,current.tOpacity):helper.parent.fadeIn(settings(current).fade);}else{helper.parent.show();}update();}function update(event){if($.tooltip.blocked)return;if(event&&event.target.tagName=="OPTION"){return;}if(!track&&helper.parent.is(":visible")){$(document.body).unbind('mousemove',update)}if(current==null){$(document.body).unbind('mousemove',update);return;}helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");var left=helper.parent[0].offsetLeft;var top=helper.parent[0].offsetTop;if(event){left=event.pageX+settings(current).left;top=event.pageY+settings(current).top;var right='auto';if(settings(current).positionLeft){right=$(window).width()-left;left='auto';}helper.parent.css({left:left,right:right,top:top});}var v=viewport(),h=helper.parent[0];if(v.x+v.cx<h.offsetLeft+h.offsetWidth){left-=h.offsetWidth+20+settings(current).left;helper.parent.css({left:left+'px'}).addClass("viewport-right");}if(v.y+v.cy<h.offsetTop+h.offsetHeight){top-=h.offsetHeight+20+settings(current).top;helper.parent.css({top:top+'px'}).addClass("viewport-bottom");}}function viewport(){return{x:$(window).scrollLeft(),y:$(window).scrollTop(),cx:$(window).width(),cy:$(window).height()};}function hide(event){if($.tooltip.blocked)return;if(tID)clearTimeout(tID);current=null;var tsettings=settings(this);function complete(){helper.parent.removeClass(tsettings.extraClass).hide().css("opacity","");}if((!IE||!$.fn.bgiframe)&&tsettings.fade){if(helper.parent.is(':animated'))helper.parent.stop().fadeTo(tsettings.fade,0,complete);else
-helper.parent.stop().fadeOut(tsettings.fade,complete);}else
-complete();if(settings(this).fixPNG)helper.parent.unfixPNG();}})(jQuery);
\ No newline at end of file

=== removed file 'dashboard_app/static/dashboard_app/js/jstorage.min.js'
--- dashboard_app/static/dashboard_app/js/jstorage.min.js	2013-06-10 12:19:28 +0000
+++ dashboard_app/static/dashboard_app/js/jstorage.min.js	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-/*
- * ----------------------------- JSTORAGE -------------------------------------
- * Simple local storage wrapper to save data on the browser side, supporting
- * all major browsers - IE6+, Firefox2+, Safari4+, Chrome4+ and Opera 10.5+
- *
- * Copyright (c) 2010 - 2012 Andris Reinman, andris.reinman@gmail.com
- * Project homepage: www.jstorage.info
- *
- * Licensed under MIT-style license:
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-
-(function(){var JSTORAGE_VERSION="0.4.3",$=window.jQuery||window.$||(window.$={}),JSON={parse:window.JSON&&(window.JSON.parse||window.JSON.decode)||String.prototype.evalJSON&&function(str){return String(str).evalJSON()}||$.parseJSON||$.evalJSON,stringify:Object.toJSON||window.JSON&&(window.JSON.stringify||window.JSON.encode)||$.toJSON};if(!JSON.parse||!JSON.stringify){throw new Error("No JSON support found, include //cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js to page")}var _storage={__jstorage_meta:{CRC32:{}}},_storage_service={jStorage:"{}"},_storage_elm=null,_storage_size=0,_backend=false,_observers={},_observer_timeout=false,_observer_update=0,_pubsub_observers={},_pubsub_last=+new Date(),_ttl_timeout,_XMLService={isXML:function(elm){var documentElement=(elm?elm.ownerDocument||elm:0).documentElement;return documentElement?documentElement.nodeName!=="HTML":false},encode:function(xmlNode){if(!this.isXML(xmlNode)){return false}try{return new XMLSerializer().serializeToString(xmlNode)}catch(E1){try{return xmlNode.xml}catch(E2){}}return false},decode:function(xmlString){var dom_parser=("DOMParser"in window&&(new DOMParser()).parseFromString)||(window.ActiveXObject&&function(_xmlString){var xml_doc=new ActiveXObject('Microsoft.XMLDOM');xml_doc.async='false';xml_doc.loadXML(_xmlString);return xml_doc}),resultXML;if(!dom_parser){return false}resultXML=dom_parser.call("DOMParser"in window&&(new DOMParser())||window,xmlString,'text/xml');return this.isXML(resultXML)?resultXML:false}};function _init(){var localStorageReallyWorks=false;if("localStorage"in window){try{window.localStorage.setItem('_tmptest','tmpval');localStorageReallyWorks=true;window.localStorage.removeItem('_tmptest')}catch(BogusQuotaExceededErrorOnIos5){}}if(localStorageReallyWorks){try{if(window.localStorage){_storage_service=window.localStorage;_backend="localStorage";_observer_update=_storage_service.jStorage_update}}catch(E3){}}else if("globalStorage"in window){try{if(window.globalStorage){if(window.location.hostname=='localhost'){_storage_service=window.globalStorage['localhost.localdomain']}else{_storage_service=window.globalStorage[window.location.hostname]}_backend="globalStorage";_observer_update=_storage_service.jStorage_update}}catch(E4){}}else{_storage_elm=document.createElement('link');if(_storage_elm.addBehavior){_storage_elm.style.behavior='url(#default#userData)';document.getElementsByTagName('head')[0].appendChild(_storage_elm);try{_storage_elm.load("jStorage")}catch(E){_storage_elm.setAttribute("jStorage","{}");_storage_elm.save("jStorage");_storage_elm.load("jStorage")}var data="{}";try{data=_storage_elm.getAttribute("jStorage")}catch(E5){}try{_observer_update=_storage_elm.getAttribute("jStorage_update")}catch(E6){}_storage_service.jStorage=data;_backend="userDataBehavior"}else{_storage_elm=null;return}}_load_storage();_handleTTL();_setupObserver();_handlePubSub();if("addEventListener"in window){window.addEventListener("pageshow",function(event){if(event.persisted){_storageObserver()}},false)}}function _reloadData(){var data="{}";if(_backend=="userDataBehavior"){_storage_elm.load("jStorage");try{data=_storage_elm.getAttribute("jStorage")}catch(E5){}try{_observer_update=_storage_elm.getAttribute("jStorage_update")}catch(E6){}_storage_service.jStorage=data}_load_storage();_handleTTL();_handlePubSub()}function _setupObserver(){if(_backend=="localStorage"||_backend=="globalStorage"){if("addEventListener"in window){window.addEventListener("storage",_storageObserver,false)}else{document.attachEvent("onstorage",_storageObserver)}}else if(_backend=="userDataBehavior"){setInterval(_storageObserver,1000)}}function _storageObserver(){var updateTime;clearTimeout(_observer_timeout);_observer_timeout=setTimeout(function(){if(_backend=="localStorage"||_backend=="globalStorage"){updateTime=_storage_service.jStorage_update}else if(_backend=="userDataBehavior"){_storage_elm.load("jStorage");try{updateTime=_storage_elm.getAttribute("jStorage_update")}catch(E5){}}if(updateTime&&updateTime!=_observer_update){_observer_update=updateTime;_checkUpdatedKeys()}},25)}function _checkUpdatedKeys(){var oldCrc32List=JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32)),newCrc32List;_reloadData();newCrc32List=JSON.parse(JSON.stringify(_storage.__jstorage_meta.CRC32));var key,updated=[],removed=[];for(key in oldCrc32List){if(oldCrc32List.hasOwnProperty(key)){if(!newCrc32List[key]){removed.push(key);continue}if(oldCrc32List[key]!=newCrc32List[key]&&String(oldCrc32List[key]).substr(0,2)=="2."){updated.push(key)}}}for(key in newCrc32List){if(newCrc32List.hasOwnProperty(key)){if(!oldCrc32List[key]){updated.push(key)}}}_fireObservers(updated,"updated");_fireObservers(removed,"deleted")}function _fireObservers(keys,action){keys=[].concat(keys||[]);if(action=="flushed"){keys=[];for(var key in _observers){if(_observers.hasOwnProperty(key)){keys.push(key)}}action="deleted"}for(var i=0,len=keys.length;i<len;i++){if(_observers[keys[i]]){for(var j=0,jlen=_observers[keys[i]].length;j<jlen;j++){_observers[keys[i]][j](keys[i],action)}}if(_observers["*"]){for(var j=0,jlen=_observers["*"].length;j<jlen;j++){_observers["*"][j](keys[i],action)}}}}function _publishChange(){var updateTime=(+new Date()).toString();if(_backend=="localStorage"||_backend=="globalStorage"){_storage_service.jStorage_update=updateTime}else if(_backend=="userDataBehavior"){_storage_elm.setAttribute("jStorage_update",updateTime);_storage_elm.save("jStorage")}_storageObserver()}function _load_storage(){if(_storage_service.jStorage){try{_storage=JSON.parse(String(_storage_service.jStorage))}catch(E6){_storage_service.jStorage="{}"}}else{_storage_service.jStorage="{}"}_storage_size=_storage_service.jStorage?String(_storage_service.jStorage).length:0;if(!_storage.__jstorage_meta){_storage.__jstorage_meta={}}if(!_storage.__jstorage_meta.CRC32){_storage.__jstorage_meta.CRC32={}}}function _save(){_dropOldEvents();try{_storage_service.jStorage=JSON.stringify(_storage);if(_storage_elm){_storage_elm.setAttribute("jStorage",_storage_service.jStorage);_storage_elm.save("jStorage")}_storage_size=_storage_service.jStorage?String(_storage_service.jStorage).length:0}catch(E7){}}function _checkKey(key){if(!key||(typeof key!="string"&&typeof key!="number")){throw new TypeError('Key name must be string or numeric')}if(key=="__jstorage_meta"){throw new TypeError('Reserved key name')}return true}function _handleTTL(){var curtime,i,TTL,CRC32,nextExpire=Infinity,changed=false,deleted=[];clearTimeout(_ttl_timeout);if(!_storage.__jstorage_meta||typeof _storage.__jstorage_meta.TTL!="object"){return}curtime=+new Date();TTL=_storage.__jstorage_meta.TTL;CRC32=_storage.__jstorage_meta.CRC32;for(i in TTL){if(TTL.hasOwnProperty(i)){if(TTL[i]<=curtime){delete TTL[i];delete CRC32[i];delete _storage[i];changed=true;deleted.push(i)}else if(TTL[i]<nextExpire){nextExpire=TTL[i]}}}if(nextExpire!=Infinity){_ttl_timeout=setTimeout(_handleTTL,nextExpire-curtime)}if(changed){_save();_publishChange();_fireObservers(deleted,"deleted")}}function _handlePubSub(){var i,len;if(!_storage.__jstorage_meta.PubSub){return}var pubelm,_pubsubCurrent=_pubsub_last;for(i=len=_storage.__jstorage_meta.PubSub.length-1;i>=0;i--){pubelm=_storage.__jstorage_meta.PubSub[i];if(pubelm[0]>_pubsub_last){_pubsubCurrent=pubelm[0];_fireSubscribers(pubelm[1],pubelm[2])}}_pubsub_last=_pubsubCurrent}function _fireSubscribers(channel,payload){if(_pubsub_observers[channel]){for(var i=0,len=_pubsub_observers[channel].length;i<len;i++){_pubsub_observers[channel][i](channel,JSON.parse(JSON.stringify(payload)))}}}function _dropOldEvents(){if(!_storage.__jstorage_meta.PubSub){return}var retire=+new Date()-2000;for(var i=0,len=_storage.__jstorage_meta.PubSub.length;i<len;i++){if(_storage.__jstorage_meta.PubSub[i][0]<=retire){_storage.__jstorage_meta.PubSub.splice(i,_storage.__jstorage_meta.PubSub.length-i);break}}if(!_storage.__jstorage_meta.PubSub.length){delete _storage.__jstorage_meta.PubSub}}function _publish(channel,payload){if(!_storage.__jstorage_meta){_storage.__jstorage_meta={}}if(!_storage.__jstorage_meta.PubSub){_storage.__jstorage_meta.PubSub=[]}_storage.__jstorage_meta.PubSub.unshift([+new Date,channel,payload]);_save();_publishChange()}function murmurhash2_32_gc(str,seed){var l=str.length,h=seed^l,i=0,k;while(l>=4){k=((str.charCodeAt(i)&0xff))|((str.charCodeAt(++i)&0xff)<<8)|((str.charCodeAt(++i)&0xff)<<16)|((str.charCodeAt(++i)&0xff)<<24);k=(((k&0xffff)*0x5bd1e995)+((((k>>>16)*0x5bd1e995)&0xffff)<<16));k^=k>>>24;k=(((k&0xffff)*0x5bd1e995)+((((k>>>16)*0x5bd1e995)&0xffff)<<16));h=(((h&0xffff)*0x5bd1e995)+((((h>>>16)*0x5bd1e995)&0xffff)<<16))^k;l-=4;++i}switch(l){case 3:h^=(str.charCodeAt(i+2)&0xff)<<16;case 2:h^=(str.charCodeAt(i+1)&0xff)<<8;case 1:h^=(str.charCodeAt(i)&0xff);h=(((h&0xffff)*0x5bd1e995)+((((h>>>16)*0x5bd1e995)&0xffff)<<16))}h^=h>>>13;h=(((h&0xffff)*0x5bd1e995)+((((h>>>16)*0x5bd1e995)&0xffff)<<16));h^=h>>>15;return h>>>0}$.jStorage={version:JSTORAGE_VERSION,set:function(key,value,options){_checkKey(key);options=options||{};if(typeof value=="undefined"){this.deleteKey(key);return value}if(_XMLService.isXML(value)){value={_is_xml:true,xml:_XMLService.encode(value)}}else if(typeof value=="function"){return undefined}else if(value&&typeof value=="object"){value=JSON.parse(JSON.stringify(value))}_storage[key]=value;_storage.__jstorage_meta.CRC32[key]="2."+murmurhash2_32_gc(JSON.stringify(value),0x9747b28c);this.setTTL(key,options.TTL||0);_fireObservers(key,"updated");return value},get:function(key,def){_checkKey(key);if(key in _storage){if(_storage[key]&&typeof _storage[key]=="object"&&_storage[key]._is_xml){return _XMLService.decode(_storage[key].xml)}else{return _storage[key]}}return typeof(def)=='undefined'?null:def},deleteKey:function(key){_checkKey(key);if(key in _storage){delete _storage[key];if(typeof _storage.__jstorage_meta.TTL=="object"&&key in _storage.__jstorage_meta.TTL){delete _storage.__jstorage_meta.TTL[key]}delete _storage.__jstorage_meta.CRC32[key];_save();_publishChange();_fireObservers(key,"deleted");return true}return false},setTTL:function(key,ttl){var curtime=+new Date();_checkKey(key);ttl=Number(ttl)||0;if(key in _storage){if(!_storage.__jstorage_meta.TTL){_storage.__jstorage_meta.TTL={}}if(ttl>0){_storage.__jstorage_meta.TTL[key]=curtime+ttl}else{delete _storage.__jstorage_meta.TTL[key]}_save();_handleTTL();_publishChange();return true}return false},getTTL:function(key){var curtime=+new Date(),ttl;_checkKey(key);if(key in _storage&&_storage.__jstorage_meta.TTL&&_storage.__jstorage_meta.TTL[key]){ttl=_storage.__jstorage_meta.TTL[key]-curtime;return ttl||0}return 0},flush:function(){_storage={__jstorage_meta:{CRC32:{}}};_save();_publishChange();_fireObservers(null,"flushed");return true},storageObj:function(){function F(){}F.prototype=_storage;return new F()},index:function(){var index=[],i;for(i in _storage){if(_storage.hasOwnProperty(i)&&i!="__jstorage_meta"){index.push(i)}}return index},storageSize:function(){return _storage_size},currentBackend:function(){return _backend},storageAvailable:function(){return!!_backend},listenKeyChange:function(key,callback){_checkKey(key);if(!_observers[key]){_observers[key]=[]}_observers[key].push(callback)},stopListening:function(key,callback){_checkKey(key);if(!_observers[key]){return}if(!callback){delete _observers[key];return}for(var i=_observers[key].length-1;i>=0;i--){if(_observers[key][i]==callback){_observers[key].splice(i,1)}}},subscribe:function(channel,callback){channel=(channel||"").toString();if(!channel){throw new TypeError('Channel not defined')}if(!_pubsub_observers[channel]){_pubsub_observers[channel]=[]}_pubsub_observers[channel].push(callback)},publish:function(channel,payload){channel=(channel||"").toString();if(!channel){throw new TypeError('Channel not defined')}_publish(channel,payload)},reInit:function(){_reloadData()}};_init()})();

=== removed directory 'dashboard_app/templates'
=== removed directory 'dashboard_app/templates/admin'
=== removed directory 'dashboard_app/templates/admin/dashboard_app'
=== removed file 'dashboard_app/templates/admin/dashboard_app/cleanup_selected_bundle_confirmation.html'
--- dashboard_app/templates/admin/dashboard_app/cleanup_selected_bundle_confirmation.html	2012-06-07 18:45:54 +0000
+++ dashboard_app/templates/admin/dashboard_app/cleanup_selected_bundle_confirmation.html	1970-01-01 00:00:00 +0000
@@ -1,47 +0,0 @@
-{% extends "admin/base_site.html" %}
-{% load i18n l10n %}
-
-{% block breadcrumbs %}
-<div class="breadcrumbs">
-     <a href="../../">{% trans "Home" %}</a> &rsaquo;
-     <a href="../">{{ app_label|capfirst }}</a> &rsaquo;
-     <a href="./">{{ opts.verbose_name_plural|capfirst }}</a> &rsaquo;
-     {% trans 'Delete multiple objects' %}
-</div>
-{% endblock %}
-
-{% block content %}
-{% if perms_lacking or protected %}
-    {% if perms_lacking %}
-        <p>{% blocktrans %}Deleting the selected {{ objects_name }} would result in deleting related objects, but your account doesn't have permission to delete the following types of objects:{% endblocktrans %}</p>
-        <ul>
-        {% for obj in perms_lacking %}
-            <li>{{ obj }}</li>
-        {% endfor %}
-        </ul>
-    {% endif %}
-    {% if protected %}
-        <p>{% blocktrans %}Deleting the selected {{ objects_name }} would require deleting the following protected related objects:{% endblocktrans %}</p>
-        <ul>
-        {% for obj in protected %}
-            <li>{{ obj }}</li>
-        {% endfor %}
-        </ul>
-    {% endif %}
-{% else %}
-    <p>{% blocktrans %}Are you sure you want to delete the selected {{ objects_name }}? All of the following objects and their related items will be deleted:{% endblocktrans %}</p>
-    {% for deletable_object in deletable_objects %}
-        <ul>{{ deletable_object|unordered_list }}</ul>
-    {% endfor %}
-    <form action="" method="post">{% csrf_token %}
-    <div>
-    {% for obj in queryset %}
-    <input type="hidden" name="{{ action_checkbox_name }}" value="{{ obj.pk|unlocalize }}" />
-    {% endfor %}
-    <input type="hidden" name="action" value="cleanup_bundle_stream_selected" />
-    <input type="hidden" name="post" value="yes" />
-    <input type="submit" value="{% trans "Yes, I'm sure" %}" />
-    </div>
-    </form>
-{% endif %}
-{% endblock %}

=== removed directory 'dashboard_app/templates/dashboard_app'
=== removed file 'dashboard_app/templates/dashboard_app/_ajax_bundle_viewer.html'
--- dashboard_app/templates/dashboard_app/_ajax_bundle_viewer.html	2011-07-12 02:34:12 +0000
+++ dashboard_app/templates/dashboard_app/_ajax_bundle_viewer.html	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-{% load i18n %}
-{% load stylize %}
-
-
-{% with bundle.get_sanitized_bundle as sanitized_bundle %}
-{% if sanitized_bundle.did_remove_attachments %}
-<div class="ui-widget">
-  <div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0.7em">
-  <span class="ui-icon ui-icon-info" style="float: left; margin-right: 0.3em;"></span>
-  <strong>Note:</strong> Inline attachments were removed to make this page more readable.
-  </div>
-</div>
-{% endif %}
-<div style="overflow-x: scroll">
-  {% stylize "js" %}{{ sanitized_bundle.get_human_readable_json|safe }}{% endstylize %}
-</div>
-{% endwith %}

=== removed file 'dashboard_app/templates/dashboard_app/_attachments.html'
--- dashboard_app/templates/dashboard_app/_attachments.html	2012-12-10 01:28:50 +0000
+++ dashboard_app/templates/dashboard_app/_attachments.html	1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
-{% if attachments.all %}
-<ul class="attachments">
-  {% for attachment in attachments.all %}
-  <li>
-    <b>{{ attachment }}</b> ({{attachment.mime_type}})
-    {% if attachment.content %}
-    ({{ attachment.get_content_size }})
-    <br />
-    <a href="{{ attachment.get_download_url }}">download</a>
-    {% if attachment.is_viewable %}
-    &nbsp;<a href="{{ attachment.get_view_url }}">view</a>
-    {% endif %}
-    {% endif %}
-    {% if attachment.public_url %}
-    <br />
-    <a href="{{ attachment.public_url }}">{{ attachment.public_url }}</a>
-    {% endif %}
-  </li>
-  {% endfor %}
-</ul>
-{% else %}
-<i>none</i>
-{% endif %}

=== removed file 'dashboard_app/templates/dashboard_app/_bundle_stream_sidebar.html'
--- dashboard_app/templates/dashboard_app/_bundle_stream_sidebar.html	2011-07-12 02:34:12 +0000
+++ dashboard_app/templates/dashboard_app/_bundle_stream_sidebar.html	1970-01-01 00:00:00 +0000
@@ -1,74 +0,0 @@
-{% load i18n %}
-<h3>{% trans "About" %}</h3>
-<dl>
-  <dt>{% trans "Pathname:" %}</dt>
-  <dd>{{ bundle_stream.pathname }}</dd>
-  <dt>{% trans "Name:" %}</dt>
-  <dd>{{ bundle_stream.name|default:"<i>not set</i>" }}</dd>
-</dl>
-<h3>{% trans "Ownership" %}</h3>
-{% if bundle_stream.user %}
-<p>{% trans "This stream is owned by" %} <q>{{ bundle_stream.user }}</q></p>
-{% else %}
-<p>{% trans "This stream is owned by group called" %} <q>{{ bundle_stream.group }}</q></p>
-{% endif %}
-<h3>{% trans "Access rights" %}</h3>
-<dl>
-  <dt>{% trans "Stream type:" %}</dt>
-  {% if bundle_stream.is_anonymous %}
-  <dd>
-  Anonymous stream <a href="#" id="what-are-anonymous-streams">(what is this?)</a>
-  <div id="dialog-message" title="{% trans "About anonymous streams" %}">
-    <p>The dashboard has several types of containers for test results. One of the
-    most common and the oldest one is an <em>anonymous stream</em>. Anonymous
-    streams act like public FTP servers. Anyone can download or upload files at
-    will. There are some restrictions, nobody can change or remove existing
-    files</p>
-
-    <p>When a stream is anonymous anonyone can upload new test results and the
-    identity of the uploading user is not recorded in the system. Anonymous
-    streams have to be public (granting read access to everyone)</p>
-
-    <div class="ui-widget">
-      <div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0.7em">
-      <span class="ui-icon ui-icon-info" style="float: left; margin-right: 0.3em;"></span>
-      <strong>Note:</strong> A stream can be marked as anonymous in the administration panel
-      </div>
-    </div>
-  </div>
-  <script type="text/javascript">
-    $(function() {
-        $( "#dialog-message" ).dialog({
-          autoOpen: false,
-          modal: true,
-          minWidth: 500,
-          buttons: {
-            Ok: function() {
-              $( this ).dialog( "close" );
-            }
-          }
-        });
-        $( "#what-are-anonymous-streams" ).click(function(e) {
-          $( "#dialog-message").dialog('open');
-        });
-      });
-  </script>
-  </dd>
-  <dt>{% trans "Read access:" %}</dt>
-  <dd>{% trans "Anyone can download or read test results uploaded here" %}</dd>
-  <dt>{% trans "Write access:" %}</dt>
-  <dd>{% trans "Anyone can upload test results here" %}</dt>
-  {% else %}
-    {% if  bundle_stream.is_public %}
-    <dd>{% trans "Public stream" %}</dd>
-    <dt>{% trans "Read access:" %}</dt>
-    <dd>{% trans "Anyone can download or read test results uploaded here" %}</dd>
-    {% else %}
-    <dd>{% trans "Private stream" %}</dd>
-    <dt>{% trans "Read access:" %}</dt>
-    <dd>{% trans "Only the owner can download or read test results uploaded here" %}</dd>
-    {% endif %}
-    <dt>{% trans "Write access:" %}</dt>
-    <dd>{% trans "Only the owner can upload test results here" %}</dd>
-  {% endif %}
-</dl>

=== removed file 'dashboard_app/templates/dashboard_app/_content.html'
--- dashboard_app/templates/dashboard_app/_content.html	2011-11-22 12:00:41 +0000
+++ dashboard_app/templates/dashboard_app/_content.html	1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
-{% extends "layouts/content.html" %}
-
-
-{% block extrahead %}
-{{ block.super }}
-{% include "dashboard_app/_extrahead.html" %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/_content_with_sidebar.html'
--- dashboard_app/templates/dashboard_app/_content_with_sidebar.html	2011-11-22 12:00:41 +0000
+++ dashboard_app/templates/dashboard_app/_content_with_sidebar.html	1970-01-01 00:00:00 +0000
@@ -1,7 +0,0 @@
-{% extends "layouts/content_with_sidebar.html" %}
-
-
-{% block extrahead %}
-{{ block.super }}
-{% include "dashboard_app/_extrahead.html" %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/_extrahead.html'
--- dashboard_app/templates/dashboard_app/_extrahead.html	2011-10-13 14:40:48 +0000
+++ dashboard_app/templates/dashboard_app/_extrahead.html	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava-server/css/demo_table_jui.css"/>
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/dashboard.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/FixedHeader.min.js"></script> 
-<script type="text/javascript" src="{{ STATIC_URL }}lava-server/js/jquery.dataTables.min.js"></script> 

=== removed file 'dashboard_app/templates/dashboard_app/_test_run_list_table.html'
--- dashboard_app/templates/dashboard_app/_test_run_list_table.html	2013-09-05 10:26:43 +0000
+++ dashboard_app/templates/dashboard_app/_test_run_list_table.html	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-{% load i18n %}
-<table class="demo_jui display" id="test_runs">
-  <thead>
-    <tr>
-      <th>{% trans "Device" %}</th>
-      <th>{% trans "Test Run" %}</th>
-      <th>{% trans "Test" %}</th>
-      <th>{% trans "Passes" %}</th>
-      <th>{% trans "Fail" %}</th>
-      <th>{% trans "Uploaded On" %} </th>
-      <th>{% trans "Analyzed On" %}</th>
-    </tr>
-  </thead>
-  <tbody>
-    {% for test_run in test_run_list %}
-    <tr>
-      <td>{{ test_run.show_device }}</td>
-      <td><a href="{{ test_run.get_absolute_url }}"><code>{{ test_run.test }} results<code/></a></td>
-      <td>{{ test_run.test }}</td>
-      <td>{{ test_run.get_summary_results.pass }}</td>
-      <td>{{ test_run.get_summary_results.fail }}</td>
-      <td>{{ test_run.bundle.uploaded_on|date:"Y-m-d H:i:s" }}</td>
-      <td>{{ test_run.analyzer_assigned_date|date:"Y-m-d H:i:s" }}</td>
-    </tr>
-    {% endfor %}
-  </tbody>
-</table>

=== removed file 'dashboard_app/templates/dashboard_app/add_test_definition.html'
--- dashboard_app/templates/dashboard_app/add_test_definition.html	2013-03-25 21:49:16 +0000
+++ dashboard_app/templates/dashboard_app/add_test_definition.html	1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-{% load i18n %}
-{% load stylize %}
-
-{% block extrahead %}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava-server/css/demo_table_jui.css"/>
-{% endblock %}
-
-{% block sidebar %}
-<h3>Actions</h3>
-<ul>
-  <li><a href="{% url dashboard_app.views.test_definition %}">
-      List test definitions</a></li>
-  <li><a href="{% url dashboard_app.views.add_test_definition %}">
-      Add test definition</a></li>
-</ul>
-{% endblock %}
-
-{% block content %}
-<form method="post" action="">
-  {% csrf_token %}
-  <table>{{ form.as_table }}</table>
-  <input type="submit" value="Save"/>
-</form>
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/attachment_view.html'
--- dashboard_app/templates/dashboard_app/attachment_view.html	2012-12-11 02:14:29 +0000
+++ dashboard_app/templates/dashboard_app/attachment_view.html	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-{% extends "layouts/base.html" %}
-
-{% block extrahead %}
-<style type="text/css">
-body { background: white; color: black; padding: 0.5em; }
-pre:target { background: rgb(255, 128, 128); }
-pre { margin: 0; }
-p.footer {
-  background: rgba(32, 32, 32);
-  background: rgba(32, 32, 32, 0.8);
-  color: #eee;
-  margin:0;
-  padding: 1em;
-  position: fixed;
-  left: 0;
-  bottom: 0;
-  width: 100%;
-}
-</style>
-{% endblock %}
-
-{% block body %}
-<p class="footer">
-Attachment &ldquo;{{ attachment.content_filename }}&rdquo; of <a href="{{ attachment.content_object.get_absolute_url }}">{{ attachment.content_object }}</a>
-</p>
-{% for line in attachment.content %}<pre id="L{{forloop.counter}}">{{line}}</pre>{% endfor %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/bundle_detail.html'
--- dashboard_app/templates/dashboard_app/bundle_detail.html	2013-09-04 16:43:10 +0000
+++ dashboard_app/templates/dashboard_app/bundle_detail.html	1970-01-01 00:00:00 +0000
@@ -1,125 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-{% load humanize %}
-{% load i18n %}
-{% load stylize %}
-
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/pygments.css"/>
-{% endblock %}
-
-
-
-{% block sidebar %}
-<h3>Permalink</h3>
-<p>You can navigate to this bundle, regardless of the bundle stream it is
-located in, by using this <a href="{{bundle.get_permalink}}">permalink</a></p>
-
-<h3>Upload details</h3>
-{% if bundle.uploaded_by %}
-<p>This bundle was uploaded by <strong>{{bundle.uploaded_by}}</strong> on
-{{bundle.uploaded_on}} ({{bundle.uploaded_on|timesince}} ago)</p>
-{% else %}
-<p>This bundle was uploaded by an anonymous contributor on
-{{bundle.uploaded_on}} ({{bundle.uploaded_on|timesince}} ago)</p>
-{% endif %}
-
-{% if bundle.testjob %}
-<h3>Job details</h3>
-<dl>
-  <dt>Job id</dt>
-  <dd><a href="{{ bundle.testjob.get_absolute_url }}">{{ bundle.testjob.id }}</a></dd>
-  <dt>Start time</dt>
-  <dd>{{ bundle.testjob.start_time }}</dd>
-  <dt>End time</dt>
-  <dd>{{ bundle.testjob.end_time }}</dd>
-</dl>
-{% endif %}
-
-<h3>File details</h3>
-<dl>
-  <dt>Declared file name:</dt>
-  <dd><q>{{ bundle.content_filename }}</q></dd>
-  <dt>Content SHA1:</dt>
-  <dd>{{ bundle.content_sha1 }}</dd>
-  <dt>Content size:</dt>
-  <dd>{{ bundle.get_content_size }}</dd>
-</dl>
-
-<h3>Storage and format</h3>
-<dl>
-  <dt>Document format:</dt>
-  <dd><q>{{bundle.get_document_format}}</q></dd>
-  <dt>Serialization format:</dt>
-  <dd><q>{{ bundle.get_serialization_format}}</q></dd>
-</dl>
-
-<h3>Tips</h3>
-<p>You can download this bundle with the following command:</p>
-<div class="console">
-{% if bundle.private %}
-  <code>lava-tool get --dashboard-url=http://{{request.user.username}}@{{site.domain}}{% url lava.api_handler %} {{bundle.content_sha1}}</code>
-{% else %}
-  <code>lava-tool get --dashboard-url=http://{{site.domain}}{% url lava.api_handler %} {{bundle.content_sha1}}</code>
-{% endif %}
-</div>
-{% endblock %}
-
-
-{% block content %}
-<script type="text/javascript">
-  $(document).ready(function() {
-    $("#tabs").tabs({
-      cache: true,
-      show: function(event, ui) {
-        var oTable = $('div.dataTables_scrollBody>table.display', ui.panel).dataTable();
-        if ( oTable.length > 0 ) {
-          oTable.fnAdjustColumnSizing();
-        }
-      },
-      ajaxOptions: {
-        dataType: "html",
-        error: function( xhr, status, index, anchor ) {
-          $( anchor.hash ).html(
-          "Couldn't load this tab. We'll try to fix this as soon as possible.");
-        }
-      }
-    });
-    $('#test_runs').dataTable({
-      bJQueryUI: true,
-      sPaginationType: "full_numbers",
-      aaSorting: [[0, "desc"]],
-    });
-  });
-</script>
-<div id="tabs">
-  <ul>
-    {% if bundle.is_deserialized %}
-    <li><a href="#tab-test-runs">{% trans "Test Runs" %}</a></li>
-    {% endif %}
-    {% if bundle.deserialization_error %}
-    <li><a href="#tab-deserialization-error">{% trans "Deserialization Error" %}</a></li>
-    {% endif %}
-    <li><a href="{% url dashboard_app.views.ajax_bundle_viewer bundle.pk %}">{% trans "Bundle Viewer" %}</a></li>
-  </ul>
-  {% if bundle.is_deserialized %}
-  <div id="tab-test-runs">
-    {% with bundle.test_runs.all as test_run_list %}
-    {% include "dashboard_app/_test_run_list_table.html" %}
-    {% endwith %}
-  </div>
-  {% endif %}
-
-  {% if bundle.deserialization_error %}
-  <div id="tab-deserialization-error">
-    <h3>Cause</h3>
-    <p>{{ bundle.deserialization_error.error_message }}</p>
-    <h3>Deserialization failure traceback</h3>
-    <div style="overflow-x: scroll">
-      {% stylize "pytb" %}{{ bundle.deserialization_error.traceback|safe }}{% endstylize %}
-    </div>
-  </div>
-  {% endif %}
-</div>
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/bundle_list.html'
--- dashboard_app/templates/dashboard_app/bundle_list.html	2012-03-12 21:00:15 +0000
+++ dashboard_app/templates/dashboard_app/bundle_list.html	1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-
-{% load django_tables2 %}
-{% load i18n %}
-{% load humanize %}
-
-
-{% block content %}
-<div id="master-toolbar-splice" >
-  <span
-    class="length"
-    style="float:left; display:inline-block; text-align:left;"></span>
-  <span
-    class="view-as"
-    style="text-align:center; display: inline-block; width:auto">
-    <input name="radio" checked type="radio" id="as_bundles"/>
-    <label for="as_bundles">
-      <a
-        id="as_bundles_link"
-        href="{% url dashboard_app.views.bundle_list bundle_stream.pathname %}"
-        >{% trans "Bundles" %}</a>
-    </label>
-    <input name="radio" type="radio" id="as_test_runs"/>
-    <label for="as_test_runs">
-      <a
-        id="as_test_runs_link"
-        href="{% url dashboard_app.views.test_run_list bundle_stream.pathname %}"
-        >{% trans "Test Runs" %}</a>
-    </label>
-  </span>
-  <span
-    class="search"
-    style="float:right; display:inline-block; text-align:right"></span>
-</div>
-<script type="text/javascript" charset="utf-8"> 
-  $(document).ready(function() {
-    // Try hard to make our radio boxes behave as links
-    $("#master-toolbar-splice span.view-as").buttonset();
-    $("#master-toolbar-splice span.view-as input").change(function(event) {
-      var link = $("#" + event.target.id + "_link");
-      location.href=link.attr("href");
-    });
-    // Insane splicing below
-    $("div.dataTables_length").children().appendTo("#master-toolbar-splice span.length");
-    $("div.dataTables_filter").children().appendTo("#master-toolbar-splice span.search");
-    $("#master-toolbar-splice").children().appendTo($("#master-toolbar"));
-    $("div.dataTables_length").remove();
-    $("div.dataTables_filter").remove();
-    $("#master-toolbar-splice").remove();
-    $("#master-toolbar").addClass("ui-widget-header ui-corner-tl ui-corner-tr").css(
-      "padding", "5pt").css("text-align", "center");
-  });
-</script>
-
-{% render_table bundle_table %}
-
-{% endblock %}
-
-
-{% block sidebar %}
-{% include "dashboard_app/_bundle_stream_sidebar.html" %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/bundle_stream_list.html'
--- dashboard_app/templates/dashboard_app/bundle_stream_list.html	2012-03-12 03:58:38 +0000
+++ dashboard_app/templates/dashboard_app/bundle_stream_list.html	1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-
-{% load django_tables2 %}
-{% load i18n %}
-{% load pagination_tags %}
-
-
-{% block content %}
-
-{% render_table bundle_stream_table %}
-
-{% endblock %}
-
-
-{% block sidebar %}
-<p>
-  {% blocktrans %}
-  Streams are containers for bundles and are quite similar to folders or
-  directories on your computer.
-  {% endblocktrans %}
-</p>
-<p>{% trans "Currently you have access to:" %}</p>
-<ul>
-  <li>{% trans "All public streams" %}</li>
-  {% if has_personal_streams %}
-  <li>{% trans "Your personal streams" %}</li>
-  {% endif %}
-  {% if has_team_streams %}
-  <li>{% trans "Team streams that you are a member of" %}</li>
-  {% endif %}
-</ul>
-{% if not user.is_authenticated %}
-<p>{% trans "You must" %} <a href="{% url django.contrib.auth.views.login %}">{% trans "sign in" %}</a> {% trans "to get more access" %}</p>
-{% endif %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/data_view_detail.html'
--- dashboard_app/templates/dashboard_app/data_view_detail.html	2011-07-12 02:34:12 +0000
+++ dashboard_app/templates/dashboard_app/data_view_detail.html	1970-01-01 00:00:00 +0000
@@ -1,33 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-
-{% block content %}
-<dl>
-  <dt>Name:</dt>
-  <dd>{{ data_view.name }}</dd>
-  <dt>Summary:</dt>
-  <dd>{{ data_view.summary }}</dd>
-  <dt>Documentation:</dt>
-  <dd>{{ data_view.documentation }}</dd>
-</dl>
-{% if data_view.arguments %}
-<table class="data">
-  <caption>Aruments</caption>
-  <tr>
-    <th>name</th>
-    <th>type</th>
-    <th>default</th>
-    <th>help</th>
-  </tr>
-  {% for argument in data_view.arguments %}
-  <tr>
-    <td>{{ argument.name }}</td>
-    <td>{{ argument.type }}</td>
-    <td>{{ argument.default|default_if_none:"<i>No default available</i>"  }}</td>
-    <td>{{ argument.help }}</td>
-  </tr>
-  {% endfor %}
-</table>
-{% endif %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/data_view_list.html'
--- dashboard_app/templates/dashboard_app/data_view_list.html	2013-09-04 16:43:10 +0000
+++ dashboard_app/templates/dashboard_app/data_view_list.html	1970-01-01 00:00:00 +0000
@@ -1,43 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-
-{% block content %}
-<div class="ui-widget">
-  <div class="ui-state-highlight ui-corner-all" style="margin-top: 20px; padding: 0.7em">
-    <span
-      class="ui-icon ui-icon-info"
-      style="float: left; margin-right: 0.3em;"></span>
-    <strong>Hint:</strong> To call a data view use the
-    <code>lava-tool</code> command. See 
-    <code>lava-tool query-data-view --help</code>
-    to get started.
-  </div>
-</div>
-<br/>
-<script type="text/javascript" charset="utf-8"> 
-  $(document).ready(function() {
-    oTable = $('#data_views').dataTable({
-      "bJQueryUI": true,
-      "sPaginationType": "full_numbers",
-      "aaSorting": [[0, "desc"]],
-    });
-  });
-</script> 
-<table class="demo_jui display" id="data_views">
-  <thead>
-    <tr>
-      <th>{% trans "Name" %}</th>
-      <th>{% trans "Summary" %}</th>
-    </tr>
-  </thead>
-  <tbody>
-    {% for data_view in data_view_list %}
-    <tr>
-      <td><a href="{{ data_view.get_absolute_url }}">{{ data_view.name }}</a></td>
-      <td>{{ data_view.summary }}</td>
-    </tr>
-    {% endfor %}
-  </tbody>
-</table>
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_add.html'
--- dashboard_app/templates/dashboard_app/filter_add.html	2013-01-09 00:05:14 +0000
+++ dashboard_app/templates/dashboard_app/filter_add.html	1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-{% block extrahead %}
-{{ block.super }}
-{{ form.media }}
-{% endblock %}
-
-{% block content %}
-{% if form.instance.pk %}
-<h1>Edit filter &ldquo;{{ form.instance.name }}&rdquo;…</h1>
-{% else %}
-<h1>Add new filter…</h1>
-{% endif %}
-
-<form action="" method="post">
-    {% csrf_token %}
-    {% include "dashboard_app/filter_form.html" %}
-{% if form.instance.pk %}
-    <input type="submit" value="Preview changes">
-{% else %}
-    <input type="submit" value="Preview">
-{% endif %}
-</form>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_compare_matches.html'
--- dashboard_app/templates/dashboard_app/filter_compare_matches.html	2013-01-08 21:16:54 +0000
+++ dashboard_app/templates/dashboard_app/filter_compare_matches.html	1970-01-01 00:00:00 +0000
@@ -1,28 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-<style type="text/css">
-  th.orderable.sortable a {
-    color: rgb(0, 136, 204);
-    text-decoration: underline;
-  }
-</style>
-{% endblock %}
-
-{% block content %}
-{% for trinfo in test_run_info %}
-<h3>{{ trinfo.key }} results</h3>
-{% if trinfo.only %}
-<p style="text-align: {{ trinfo.only }}">
-  Results were only present in <a href="{{ trinfo.tr.get_absolute_url }}">build {{ trinfo.tag }}</a>.
-</p>
-{% elif trinfo.table %}
-{% render_table trinfo.table %}
-{% else %}
-<p>No difference in {{ trinfo.key }} results{% if trinfo.cases %} for {{ trinfo.cases }}{% endif %}.</p>
-{% endif %}
-{% endfor %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_delete.html'
--- dashboard_app/templates/dashboard_app/filter_delete.html	2013-01-09 00:05:14 +0000
+++ dashboard_app/templates/dashboard_app/filter_delete.html	1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-{% block content %}
-<h1>Delete filter {{ filter.name }}</h1>
-
-<form action="" method="POST">
-  {% csrf_token %}
-  Do you really want to delete the filter {{ filter.name }}?
-  <input type="submit" name="yes" value="Yes">
-  <input type="submit" name="no" value="No">
-</form>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_detail.html'
--- dashboard_app/templates/dashboard_app/filter_detail.html	2013-01-10 01:34:27 +0000
+++ dashboard_app/templates/dashboard_app/filter_detail.html	1970-01-01 00:00:00 +0000
@@ -1,49 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/filter-detail.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/filter-detail.js"></script>
-{% endblock %}
-
-{% block content %}
-
-<h1>Filter {{ filter.name }}</h1>
-
-{% include "dashboard_app/filter_summary.html" with filter_data=filter.as_data %}
-
-{% if filter.owner == request.user %}
-<p>
-  You can <a href="{{ filter.get_absolute_url }}/+edit">edit</a>
-  or <a href="{{ filter.get_absolute_url }}/+delete">delete</a> this filter.
-</p>
-{% endif %}
-
-{% if subscription %}
-<p>
-  <a href="{% url dashboard_app.views.filters.views.filter_subscribe username=filter.owner.username name=filter.name %}">Manage</a> your subscription to this filter.
-</p>
-{% else %}
-<p>
-  <a href="{% url dashboard_app.views.filters.views.filter_subscribe username=filter.owner.username name=filter.name %}">Subscribe</a> to this filter.
-</p>
-{% endif %}
-
-{% render_table filter_table %}
-
-<p>
-  <button id="compare-button">Compare builds</button>
-  <span id="first-prompt" style="display:none">
-    Click a build to compare.
-  </span>
-  <span id="second-prompt" style="display:none">
-    Click build to compare with build <span id="p2-build">XXX</span>.
-  </span>
-  <span id="third-prompt" style="display:none">
-    Click <a href="#">here</a> to compare with build <span id="p3-build-1">XXX</span> with build <span id="p3-build-2">XXX</span>.
-  </span>
-</p>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_form.html'
--- dashboard_app/templates/dashboard_app/filter_form.html	2012-09-19 22:56:03 +0000
+++ dashboard_app/templates/dashboard_app/filter_form.html	1970-01-01 00:00:00 +0000
@@ -1,124 +0,0 @@
-    <p>
-      A filter matches test runs by a number of criteria.
-    </p>
-    {{ form.non_field_errors }}
-    <dl>
-      <dt>
-        Metadata:
-      </dt>
-      <dd>
-        {{ form.name.errors }}
-        {{ form.name.label_tag }}: {{ form.name }}
-        <br /><span class="helptext">{{ form.name.help_text|safe }}</span>
-        <br />{{ form.public.errors }}
-        {{ form.public }}{{ form.public.label_tag }}
-        <br /><span class="helptext">{{ form.public.help_text|safe }}</span>
-      </dd>
-      <dt>
-        {{ form.bundle_streams.label_tag }}:
-      </dt>
-      <dd>
-        {{ form.bundle_streams.errors }}
-        <div>{{ form.bundle_streams }}</div>
-        <div style="clear:left">{{ form.bundle_streams.help_text|safe }}</div>
-      </dd>
-      <dt>
-        Build Number:
-      </dt>
-      <dd>
-        {{ form.build_number_attribute.errors }}
-        {{ form.build_number_attribute.label_tag }}: {{ form.build_number_attribute }}
-        <br /><span class="helptext">{{ form.build_number_attribute.help_text|safe }}</span>
-      </dd>
-      <dt>
-        Attributes:
-      </dt>
-      <dd>
-        {% with form.attributes_formset as formset %}
-        <table id="attributes-table">
-          <thead>
-            <tr>
-              <th>
-                Name
-              </th>
-              <th>
-                Value
-              </th>
-            </tr>
-          </thead>
-          {{ formset.management_form }}
-          <tbody>
-            {% for form in formset %}
-            <tr>
-              <td class="name">
-                {{ form.name }}
-              </td>
-              <td class="value">
-                {{ form.value }}
-              </td>
-              <td>
-              </td>
-            </tr>
-            {% empty %}
-            <tr>
-            </tr>
-            {% endfor %}
-          </tbody>
-          <tfoot>
-            {% with formset.empty_form as form %}
-            <tr style="display:none" id="id_attributes_empty_form">
-              <td class="name">
-                {{ form.name }}
-              </td>
-              <td class="value">
-                {{ form.value }}
-              </td>
-              <td>
-              </td>
-            </tr>
-            {% endwith %}
-          </tfoot>
-        </table>
-        {% endwith %}
-        <br /><span class="helptext">
-          A filter can be limited to test runs with particular values for particular <b>attributes</b>.
-        </span>
-      </dd>
-      <dt>
-        Tests and test cases:
-      </dt>
-      <dd>
-        {% with form.tests_formset as formset %}
-        <table id="tests-table">
-          <thead>
-            <tr>
-              <th>
-                Test
-              </th>
-              <th>
-                Test Cases
-              </th>
-            </tr>
-          </thead>
-          {{ formset.management_form }}
-          <tbody>
-            {% for form in formset %}
-            <tr>
-              {% include "dashboard_app/filter_form_test.html" %}
-            </tr>
-            {% empty %}
-            <tr>
-            </tr>
-            {% endfor %}
-          </tbody>
-          <tfoot>
-            {% with formset.empty_form as form %}
-            <tr style="display:none" id="id_tests_empty_form">
-              {% include "dashboard_app/filter_form_test.html" %}
-            </tr>
-            {% endwith %}
-          </tfoot>
-        </table>
-        {% endwith %}
-      </dd>
-    </dl>

=== removed file 'dashboard_app/templates/dashboard_app/filter_form_test.html'
--- dashboard_app/templates/dashboard_app/filter_form_test.html	2012-09-19 22:56:03 +0000
+++ dashboard_app/templates/dashboard_app/filter_form_test.html	1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
-              <td class="test-cell">
-                {{ form.test.errors }}
-                {{ form.test }}
-              </td>
-              <td>
-                <table class="test-case-formset">
-                  {{ form.test_case_formset.management_form }}
-                  <tbody>
-                    {% for form in form.test_case_formset %}
-                    <tr>
-                      <td>
-                        {{ form.test_case.errors }}
-                        {{ form.test_case }}
-                      </td>
-                      <td>
-                      </td>
-                    </tr>
-                    {% empty %}
-                    <tr>
-                    </tr>
-                    {% endfor %}
-                  </tbody>
-                  <tfoot>
-                    {% with form.test_case_formset as formset %}
-                    <tr style="display:none" class="test-case-formset-empty">
-                      <td>
-                        {{ formset.empty_form.test_case }}
-                      </td>
-                      <td>
-                      </td>
-                    </tr>
-                    {% endwith %}
-                  </tfoot>
-                </table>
-              </td>
-              <td>
-              </td>

=== removed file 'dashboard_app/templates/dashboard_app/filter_preview.html'
--- dashboard_app/templates/dashboard_app/filter_preview.html	2013-01-09 00:05:14 +0000
+++ dashboard_app/templates/dashboard_app/filter_preview.html	1970-01-01 00:00:00 +0000
@@ -1,53 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-{{ form.media }}
-{% endblock %}
-
-{% block content %}
-{% if form.instance.pk %}
-<h1>Previewing changes to filter &ldquo;{{ form.instance.name }}&rdquo;</h1>
-{% else %}
-<h1>Previewing new filter &ldquo;{{ form.name.value }}&rdquo;</h1>
-{% endif %}
-
-{% include "dashboard_app/filter_summary.html" with summary_data=filter.as_data %}
-
-<p>
-  These are the results matched by your filter.
-</p>
-
-{% render_table table %}
-
-<p>
-
-<form action="" method="post">
-  <p>
-    If this is what you expected, you can
-    {% if form.instance.pk %}
-    <input type="submit" name="save" value="save changes"> to the filter.
-    {% else %}
-    <input type="submit" name="save" value="save"> the filter.
-    {% endif %}
-  </p>
-  <p>
-    Otherwise, you can <a href="#" id="edit-link">edit</a> it.
-  </p>
-  {% csrf_token %}
-  <div id="filter-edit" style="display: none">
-    {% include "dashboard_app/filter_form.html" %}
-    <input type="submit" name="preview" value="Preview again">
-  </div>
-</form>
-
-
-<script type="text/javascript">
-$("#edit-link").click(function (e) {
-e.preventDefault();
-$("#filter-edit").show();
-});
-</script>
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_results_table.html'
--- dashboard_app/templates/dashboard_app/filter_results_table.html	2012-09-14 03:14:43 +0000
+++ dashboard_app/templates/dashboard_app/filter_results_table.html	1970-01-01 00:00:00 +0000
@@ -1,28 +0,0 @@
-{% extends "ajax_table.html" %}
-
-{% block table.thead %}
-{% if table.complex_header %}
-<thead>
-  <tr>
-    {% for column in table.columns %}
-    {% if not column.column.in_group %}
-    <th {{ column.attrs.th.as_html }} rowspan="2">{{ column.header }}</th>
-    {% else %}
-    {% if column.column.first_in_group %}
-    <th class="ui-state-default" colspan="{{ column.column.group_length }}">{{ column.column.group_name }}</th>
-    {% endif %}
-    {% endif %}
-    {% endfor %}
-  </tr>
-  <tr>
-    {% for column in table.columns %}
-    {% if column.column.in_group %}
-    <th {{ column.attrs.th.as_html }}>{{ column.header }}</th>
-    {% endif %}
-    {% endfor %}
-  </tr>
-</thead>
-{% else %}
-{{ block.super }}
-{% endif %}
-{% endblock table.thead %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_subscribe.html'
--- dashboard_app/templates/dashboard_app/filter_subscribe.html	2013-01-09 00:05:14 +0000
+++ dashboard_app/templates/dashboard_app/filter_subscribe.html	1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block content %}
-
-<h1>Subscribe to filter {{ filter.name }}</h1>
-
-<form action="" method="POST">
-  {% csrf_token %}
-  <p>
-    {{ form.level.help_text|safe }}
-    {{ form.level.label_tag }}:
-    {{ form.level }}
-  </p>
-  <p>
-    {% if form.instance.pk %}
-    <input type="submit" name="update" value="Update"/>
-    <input type="submit" name="unsubscribe" value="Unsubscribe"/>
-    {% else %}
-    <input type="submit" name="subscribe" value="Subscribe"/>
-    {% endif %}
-  </p>
-</form>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/filter_subscription_mail.txt'
--- dashboard_app/templates/dashboard_app/filter_subscription_mail.txt	2012-08-23 22:50:32 +0000
+++ dashboard_app/templates/dashboard_app/filter_subscription_mail.txt	1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-Dear {{ user.first_name }} {{ user.last_name }},
-
-The bundle {{ bundle.content_filename }} was uploaded at {{ bundle.uploaded_on|date:"Y-m-d H:i:s" }} by {% if bundle.uploaded_by %}{{ bundle.uploaded_by }}{% else %}an anonymous user{% endif %}.
-
-It matched the following filters that you are subscribed to:
-
-{% for match in matches %}{{ match.format_for_mail }}{% endfor %}
-You can see more details at:
-
-  {{ url_prefix }}{{ bundle.get_absolute_url }}
-
-LAVA
-Linaro Automated Validation Architecture

=== removed file 'dashboard_app/templates/dashboard_app/filter_summary.html'
--- dashboard_app/templates/dashboard_app/filter_summary.html	2012-12-12 23:49:01 +0000
+++ dashboard_app/templates/dashboard_app/filter_summary.html	1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
-<table>
-  <tr>
-    <th>
-      Bundle streams
-    </th>
-    <td>
-    {% for stream in filter_data.bundle_streams %}
-        {{stream.pathname}}{% if not forloop.last %}, {% endif %}
-    {% endfor %}
-    </td>
-  </tr>
-{% if filter_data.attributes %}
-  <tr>
-    <th>
-      Attributes
-    </th>
-    <td>
-    {% for a in filter_data.attributes %}
-    {{ a.0 }} == {{ a.1 }} <br />
-    {% endfor %}
-    </td>
-  </tr>
-{% endif %}
-{% if filter_data.build_number_attribute %}
-  <tr>
-    <th>
-      Build Number Attribute
-    </th>
-    <td>
-      {{ filter_data.build_number_attribute }}
-    </td>
-  </tr>
-{% endif %}
-  <tr>
-    <th>
-      Test cases
-    </th>
-    <td>
-      <table>
-        <tbody>
-          {% for test in filter_data.tests %}
-          <tr>
-            <td>
-              {{ test.test }}
-            </td>
-            <td>
-              {% for test_case in test.test_cases %}
-              {{ test_case }}
-              {% empty %}
-              <i>any</i>
-              {% endfor %}
-            </td>
-          </tr>
-          {% empty %}
-          <i>any</i>
-          {% endfor %}
-        </tbody>
-      </table>
-    </td>
-  </tr>
-</table>

=== removed file 'dashboard_app/templates/dashboard_app/filters_list.html'
--- dashboard_app/templates/dashboard_app/filters_list.html	2013-01-09 00:05:14 +0000
+++ dashboard_app/templates/dashboard_app/filters_list.html	1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block content %}
-<h1>Filters</h1>
-
-<p>
- A filter matches test runs by a number of criteria.
-</p>
-
-{% if user_filters_table %}
-
-<h2>Your Filters</h2>
-
-{% render_table user_filters_table %}
-
-<p>
-  <a href="{% url dashboard_app.views.filters.views.filter_add %}">Add new filter…</a>
-</p>
-
-{% else %}
-
-<p>
-  Please log in to see and manage your filters.
-</p>
-
-{% endif %}
-
-<h2>Public Filters</h2>
-
-{% render_table public_filters_table %}
-
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image-report.html'
--- dashboard_app/templates/dashboard_app/image-report.html	2013-07-01 15:49:15 +0000
+++ dashboard_app/templates/dashboard_app/image-report.html	1970-01-01 00:00:00 +0000
@@ -1,136 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-report.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/image-report.js"></script>
-<script src="{{ STATIC_URL }}dashboard_app/js/excanvas.min.js"></script>
-<script src="{{ STATIC_URL }}dashboard_app/js/jquery.flot.min.js"></script>
-<script src="{{ STATIC_URL }}dashboard_app/js/jquery.flot.dashes.min.js"></script>
-<script src="{{ STATIC_URL }}dashboard_app/js/jstorage.min.js"></script>
-<script src="{{ STATIC_URL }}dashboard_app/js/jquery.tooltip.min.js"></script>
-
-<script language="javascript">
-  chart_data = $.parseJSON($('<div/>').html("{{chart_data}}").text());
-  test_names = $.parseJSON($('<div/>').html("{{test_names}}").text());
-  columns = $.parseJSON($('<div/>').html("{{columns}}").text());
-</script>
-{% endblock %}
-
-{% block content %}
-<h1>Image Report: {{ image.name }}</h1>
-
-
-<div id="outer-container">
-<div id="inner-container">
-</div>
-<div id="legend-container">
-</div>
-</div>
-
-<div id="toggle-graph-container">
-  <input type="checkbox" id="toggle_graph" onchange="toggle_graph()" checked="checked" />
-  <label for="toggle_graph">Toggle graph</label>
-</div>
-
-<div id="filters">
-  <div id="filter_headline">Filters <a id="filter_link" href="#">Link to this filter set</a></div>
-  <div id="build_numbers_filter">
-    <div id="build_number_headline">
-      Start build number:
-    </div>
-    <span id="build_number_start_container">
-      <select id="build_number_start" onchange='update_table(columns, chart_data, test_names)'>
-      </select>
-    </span>
-
-    End build number:
-    <span id="build_number_end_container">
-      <select id="build_number_end" onchange='update_table(columns, chart_data, test_names)'>
-      </select>
-    </span>
-  </div>
-
-  <div id="tests_filter">
-    <div id="test_headline">
-      Tests:
-    </div>
-    <select id="test_select" onchange='update_table(columns, chart_data, test_names)' multiple>
-    </select>
-  </div>
-
-  <div id="target_goal_filter">
-    <div id="target_goal_headline">
-      Target Goal:
-    </div>
-    <input type="text" id="target_goal" onblur='update_table(columns, chart_data, test_names)' />
-  </div>
-
-  <div id="graph_type_filter">
-    <div id="graph_type_headline">
-      Graph type:
-    </div>
-    <input type="radio" name="graph_type" onclick='update_table(columns, chart_data, test_names)' checked value="percentage">
-    By percentage
-    </input>
-    <input type="radio" name="graph_type" onclick='update_table(columns, chart_data, test_names)' value="number">
-    By pass/fail test numbers
-    </input>
-    <input type="radio" name="graph_type" onclick='update_table(columns, chart_data, test_names)' value="measurements">
-    By measurements
-    </input>
-  </div>
-</div>
-
-
-<table id="outer-table">
-  <tr>
-    <td>
-      <table id="test-run-names" class="inner-table">
-        <thead>
-          <tr>
-            <th style='width: 170px;'>
-              Build Number
-            </th>
-          </tr>
-        </thead>
-        <tbody>
-	</tbody>
-      </table>
-    </td>
-    <td>
-      <div id="scroller">
-        <table id="results-table" class="inner-table">
-          <thead>
-	  </thead>
-	  <tbody>
-	  </tbody>
-	</table>
-      </div>
-    </td>
-  </tr>
-</table>
-
-<form method="POST"
-      action="{% url dashboard_app.views.images.link_bug_to_testrun %}"
-      id="add-bug-dialog" style="display: none">
-  {% csrf_token %}
-  <input type="hidden" name="back" value="{{ request.path }}"/>
-  <input type="hidden" name="uuid"/>
-  <div class="prev" style="display:none">
-    XXX
-  </div>
-  <input name="bug" style="width: 100%"/>
-</form>
-
-<form method="POST"
-      action="{% url dashboard_app.views.images.unlink_bug_and_testrun %}"
-      id="go-to-bug-dialog" style="display: none">
-  {% csrf_token %}
-  <input type="hidden" name="back" value="{{ request.path }}"/>
-  <input type="hidden" name="bug"/>
-  <input type="hidden" name="uuid"/>
-  <a href="">View bug XXX</a>
-</form>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image-reports.html'
--- dashboard_app/templates/dashboard_app/image-reports.html	2012-07-18 05:20:11 +0000
+++ dashboard_app/templates/dashboard_app/image-reports.html	1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-{% block content %}
-<h1>Image Reports</h1>
-
-{% for imageset in imagesets %}
-<h2>{{ imageset.name }}</h2>
-<ul>
-  {% for image in imageset.images %}
-  <li>
-    {% if image.bundle_count %}
-    <a href="{{ image.link }}">{{ image.name }}</a>
-    ({{ image.bundle_count }} results)
-    {% else %}
-    {{ image.name }} ({{ image.bundle_count }} results)
-    {% endif %}
-  </li>
-  {% endfor %}
-</ul>
-{% endfor %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image_chart_filter_form.html'
--- dashboard_app/templates/dashboard_app/image_chart_filter_form.html	2013-09-12 13:30:08 +0000
+++ dashboard_app/templates/dashboard_app/image_chart_filter_form.html	1970-01-01 00:00:00 +0000
@@ -1,109 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-charts.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/image-report-editor.js"></script>
-
-{% endblock %}
-
-
-{% block content %}
-<h1>Image Chart Filter</h1>
-
-{% block content_form %}
-<form action="" method="post">{% csrf_token %}
-
-  {% if form.errors %}
-  <div class="errors">
-    <div>
-      {{ form.non_field_errors }}
-      <ul>
-	{% for field in form %}
-	{% if field.errors %}
-        <li>{{ field.label }}: {{ field.errors|striptags }}</li>
-        {% endif %}
-	{% endfor %}
-      </ul>
-    </div>
-  </div>
-  {% endif %}
-
-  <div id="filters_div">
-    <div id="add_filter_link">
-      <a href="#" onclick="select_filter()">Select filter</a>
-      {{ form.filter }}
-      {{ form.image_chart }}
-      <input type="hidden" id="id_chart_type" value="{{ image_chart.chart_type }}"/>
-      {{ form.image_chart_tests }}
-      {{ form.image_chart_test_cases }}
-    </div>
-
-    <div>
-      {{ form.representation.label_tag }}
-      {{ form.representation }}
-    </div>
-  </div>
-
-  <div id="aliases_div">
-  </div>
-
-  <div class="submit-button">
-    <input type="submit" value="Save" />
-  </div>
-</form>
-
-{% endblock content_form %}
-
-{% render_table filters_table %}
-
-<div id="loading_dialog">
-<img src="{{ STATIC_URL }}dashboard_app/images/ajax-progress.gif" alt="Loading..." />
-</div>
-
-<script type="text/javascript">
-  $().ready(function () {
-
-    init_filter_dialog();
-    init_loading_dialog();
-
-    $('form').submit(function() {
-        add_selected_options();
-        sort_aliases();
-    });
-
-    {% if form.filter.value %}
-      filters_callback('{{ instance.filter.id }}',
-                       '{{ instance.filter.name }}');
-
-      if ($('#id_chart_type').val() == "pass/fail") {
-      {% for test in instance.imagecharttest_set.all %}
-        $('#available_tests option[value="{{ test.test_id }}"]').attr('selected', 'selected');
-      {% endfor %}
-      } else {
-      {% for test in instance.imagecharttestcase_set.all %}
-        $('#available_tests option[value="{{ test.test_case_id }}"]').attr('selected', 'selected');
-      {% endfor %}
-      }
-
-      move_options('available_tests', 'chosen_tests');
-
-      if ($('#id_chart_type').val() == "pass/fail") {
-      {% for test in instance.imagecharttest_set.all %}
-        $('#alias_{{ test.test_id }}').val('{{ test.name }}');
-      {% endfor %}
-      } else {
-      {% for test in instance.imagecharttestcase_set.all %}
-
-        $('#alias_{{ test.test_case_id }}').val('{{ test.name }}');
-      {% endfor %}
-      }
-
-    {% endif %}
-});
-
-</script>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image_report_chart_detail.html'
--- dashboard_app/templates/dashboard_app/image_report_chart_detail.html	2013-09-12 19:32:47 +0000
+++ dashboard_app/templates/dashboard_app/image_report_chart_detail.html	1970-01-01 00:00:00 +0000
@@ -1,86 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-charts.css"/>
-{% endblock %}
-
-{% block content %}
-
-<h1>Image Chart {{ image_chart.name }}</h1>
-
-
-<div class="fields-container">
-  <div class="form-field">
-    <a href="{{ image_chart.get_absolute_url }}/+edit">Edit</a> this chart.
-  </div>
-  <div class="form-field">
-    Description: {{ image_chart.description }}
-  </div>
-  <div class="form-field">
-    Chart type: {{ image_chart.chart_type }}
-  </div>
-  <div class="form-field">
-    Data table visible: {{ image_chart.is_data_table_visible }}
-  </div>
-  <div class="form-field">
-    Target goal: {{ image_chart.target_goal|floatformat:"-2" }}
-  </div>
-</div>
-
-
-<h3>Filters</h3>
-
-<div class="fields-container">
-  <div id="add_filter_link">
-    <a href="{{ image_chart.get_absolute_url }}/+add-filter">Add filter</a>
-  </div>
-</div>
-
-<div class="list-container">
-  {% for chart_filter in image_chart.imagechartfilter_set.all %}
-  <div class="chart-title">
-    {{ chart_filter.filter.name }}&nbsp;&nbsp;&nbsp;&nbsp;
-    <a style="font-size: 13px;" href="{{ chart_filter.get_absolute_url }}">
-      edit
-    </a>&nbsp;
-    <a style="font-size: 13px;" href="{{ chart_filter.get_absolute_url }}/+delete">
-      remove
-    </a>
-  </div>
-  <div>
-    {% if image_chart.chart_type == "pass/fail" %}
-      Tests:&nbsp;
-      {% for chart_test in chart_filter.imagecharttest_set.all %}
-        {% if forloop.last %}
-          {{ chart_test.test.test_id }}
-        {% else %}
-          {{ chart_test.test.test_id }},&nbsp;
-        {% endif %}
-      {% endfor %}
-    {% else %}
-      Test Cases:&nbsp
-      {% for chart_test in chart_filter.imagecharttestcase_set.all %}
-        {% if forloop.last %}
-          {{ chart_test.test_case.test_case_id }}
-        {% else %}
-          {{ chart_test.test_case.test_case_id }},&nbsp;
-        {% endif %}
-      {% endfor %}
-    {% endif %}
-  </div>
-  <div>
-    Representation: {{ chart_filter.representation }}
-  </div>
-
-  <hr/>
-  {% empty %}
-  <div>
-    <li>No filters added yet.</li>
-  </div>
-  {% endfor %}
-</div>
-
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image_report_chart_form.html'
--- dashboard_app/templates/dashboard_app/image_report_chart_form.html	2013-09-12 14:12:07 +0000
+++ dashboard_app/templates/dashboard_app/image_report_chart_form.html	1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-charts.css"/>
-
-{% endblock %}
-
-
-{% block content %}
-<h1>Add Image Charts 2.0</h1>
-
-{% block content_form %}
-<form action="" method="post">{% csrf_token %}
-
-  {% if form.errors %}
-  <div class="errors">
-    <div>
-      {{ form.non_field_errors }}
-      <ul>
-	{% for field in form %}
-	{% if field.errors %}
-        <li>{{ field.label }}: {{ field.errors|striptags }}</li>
-        {% endif %}
-	{% endfor %}
-      </ul>
-    </div>
-  </div>
-  {% endif %}
-
-  <div class="form-field">
-    {{ form.name.label_tag }}
-    {{ form.name }}
-    <input type="hidden" id="id_image_report" name="image_report" value="{{ image_report_id }}"/>
-  </div>
-  <div class="form-field">
-    {{ form.description.label_tag }}
-    {{ form.description }}
-  </div>
-  <div class="form-field">
-    {{ form.chart_type.label_tag }}
-    {{ form.chart_type }}
-  </div>
-  <div class="form-field">
-    {{ form.is_data_table_visible.label_tag }}
-    {{ form.is_data_table_visible }}
-  </div>
-  <div class="form-field">
-    {{ form.target_goal.label_tag }}
-    {{ form.target_goal }}
-  </div>
-
-  <div class="submit-button">
-    <input type="submit" value="Save" />
-  </div>
-</form>
-
-{% endblock content_form %}
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image_report_detail.html'
--- dashboard_app/templates/dashboard_app/image_report_detail.html	2013-09-12 14:12:07 +0000
+++ dashboard_app/templates/dashboard_app/image_report_detail.html	1970-01-01 00:00:00 +0000
@@ -1,80 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-charts.css"/>
-{% endblock %}
-
-{% block content %}
-
-<h1>Image Report {{ image_report.name }}</h1>
-
-<div class="fields-container">
-  <div class="form-field">
-    Status&#58;&nbsp;
-    {% if image_report.is_published %}
-    <span style="font-weight: bold; color: green;">
-      Published
-    </span>
-    {% else %}
-    <span style="font-weight: bold; color: orange;">
-      Not Published
-    </span>
-    {% endif %}
-  </div>
-  <div class="form-field">
-    Description&#58;&nbsp;{{ image_report.description }}
-  </div>
-  <div class="form-field">
-    <a href="{{ image_report.get_absolute_url }}/+edit">Edit</a> this image report.
-  </div>
-  <div class="form-field">
-    {% if image_report.is_published %}
-    <a href="{{ image_report.get_absolute_url }}/+unpublish">Unpublish</a> this image report.
-    {% else %}
-    <a href="{{ image_report.get_absolute_url }}/+publish">Publish</a> this image report.
-{% endif %}
-  </div>
-</div>
-
-<h3>Charts</h3>
-
-<div class="fields-container">
-  <a href="{% url dashboard_app.views.image_reports.views.image_chart_add %}?image_report_id={{ image_report.id }}">
-    Add new chart
-  </a>
-</div>
-
-<div class="list-container">
-  {% for image_chart in image_report.imagereportchart_set.all %}
-  <div class="chart-title">
-    {{ image_chart.name }}&nbsp;&nbsp;
-    <a style="font-size: 13px;" href="{{ image_chart.get_absolute_url }}">
-      details
-    </a>&nbsp;
-    <a style="font-size: 13px;" href="{{ image_chart.get_absolute_url }}">
-      preview
-    </a>
-  </div>
-  <div>
-    Description: {{ image_chart.description }}
-  </div>
-  <div>
-    Chart type: {{ image_chart.chart_type }}
-  </div>
-  <div>
-    Data table visible: {{ image_chart.is_data_table_visible }}
-  </div>
-  <div>
-    Target goal: {{ image_chart.target_goal|floatformat:"-2" }}
-  </div>
-  <hr/>
-  {% empty %}
-  <div>
-    <li>No charts added yet.</li>
-  </div>
-  {% endfor %}
-</div>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image_report_form.html'
--- dashboard_app/templates/dashboard_app/image_report_form.html	2013-09-12 14:12:07 +0000
+++ dashboard_app/templates/dashboard_app/image_report_form.html	1970-01-01 00:00:00 +0000
@@ -1,45 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-charts.css"/>
-{% endblock %}
-
-{% block content %}
-<h1>Image Reports 2.0</h1>
-
-{% block content_form %}
-<form action="" method="post">{% csrf_token %}
-
-  {% if form.errors %}
-  <div class="errors">
-    <div>
-      {{ form.non_field_errors }}
-      <ul>
-	{% for field in form %}
-	{% if field.errors %}
-        <li>{{ field.label }}: {{ field.errors|striptags }}</li>
-        {% endif %}
-	{% endfor %}
-      </ul>
-    </div>
-  </div>
-  {% endif %}
-
-<div class="form-field">
-  {{ form.name.label_tag }}
-  {{ form.name }}
-</div>
-<div class="form-field">
-  {{ form.description.label_tag }}
-  {{ form.description }}
-</div>
-
-<div class="submit-button">
-<input type="submit" value="Save" />
-</div>
-</form>
-
-{% endblock content_form %}
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/image_report_list.html'
--- dashboard_app/templates/dashboard_app/image_report_list.html	2013-09-11 22:18:16 +0000
+++ dashboard_app/templates/dashboard_app/image_report_list.html	1970-01-01 00:00:00 +0000
@@ -1,37 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/image-charts.css"/>
-{% endblock %}
-
-{% block content %}
-<h1>Image Reports 2.0</h1>
-
-<p style="margin-left: 10px;">
-  <a href="{% url dashboard_app.views.image_reports.views.image_report_add %}">
-    Add new Image Report
-  </a>
-</p>
-
-{% for image_report in image_reports %}
-<div class="list-container">
-  <div style="float: left;">
-    <a href="{{ image_report.get_absolute_url }}">{{ image_report.name }}</a>
-    &nbsp;&nbsp;
-  </div>
-  {% if image_report.is_published %}
-  <div style="font-weight: bold; float: right; color: green;">
-    Published
-  </div>
-  {% else %}
-  <div style="font-weight: bold; float: right; color: orange;">
-    Not Published
-  </div>
-  {% endif %}
-  <div style="clear: both;">
-    {{ image_report.description }}
-  </div>
-</div>
-{% endfor %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/index.html'
--- dashboard_app/templates/dashboard_app/index.html	2013-01-11 16:58:08 +0000
+++ dashboard_app/templates/dashboard_app/index.html	1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-
-{% block content %}
-<h1>Welcome</h1>
-<p>The <em>Validation Dashboard</em> is your window to
-test results, regardless of how your run your tests you
-can upload the results here and analyze them with simple
-built-in views. Additionally, you can export data view
-the <a href="{% url lava.api_help %}">XML-RPC API</a>
-to build your own customized reports.</p>
-
-<h2>Getting Started</h2>
-
-<p>The dashboard stores results of tests in <em>bundles</em>. These
-bundles are then grouped by a thing called <em>bundle streams</em>.
-You can drill down by viewing the
-<a href="{% url dashboard_app.views.bundle_stream_list %}">bundle stream list</a>.
-However, that view can present too much data.</p>
-
-<p>There are two good ways to limit the data in order to see the
-results you are interested in</p>
-
-<h3>Filters</h3>
-<p><a href="{% url dashboard_app.views.filters.views.filters_list %}">Filters</a>
-allow you to create your own list of criteria for what you'd like to look at.
-These can be created as "public" so others can use them, or private so only
-you can see them.</p>
-
-<h3>Image Reports</h3>
-<p><a href="{% url dashboard_app.views.images.image_report_list %}">Image Reports</a>
-are a feature built on top of filters, that allow a nice view of daily jobs
-that are being run in LAVA.</p>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/pmqa-view.html'
--- dashboard_app/templates/dashboard_app/pmqa-view.html	2013-01-10 01:56:51 +0000
+++ dashboard_app/templates/dashboard_app/pmqa-view.html	1970-01-01 00:00:00 +0000
@@ -1,87 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-
-{% block extrahead %}
-{{ block.super }}
-<style type="text/css">
-table {
-    border-collapse: collapse;
-}
-td, th {
-    min-width: 25ex;
-    padding: 3px 4px;
-    border: thin solid black;
-}
-td.pass {
-    background-color: #4e4;
-}
-td.fail {
-    background-color: #e44;
-}
-td.missing {
-    background-color: #bbb;
-}
-
-</style>
-{% endblock %}
-
-{% block content %}
-<h1>PMQA view</h1>
-
-<table>
-  <thead>
-    <tr>
-      <th>
-      </th>
-      {% for device_type in device_types_with_results %}
-      {% if device_type.width %}
-      <th colspan="{{ device_type.width }}">
-        {{ device_type.sn }}
-      </th>
-      {% endif %}
-      {% endfor %}
-    </tr>
-    <tr>
-      <th>
-      </th>
-      {% for device_type in device_types_with_results %}
-      <th>
-        <a href="{{ device_type.filter_link }}">{{ device_type.device_type }}</a>
-      </th>
-      {% endfor %}
-    </tr>
-    <tr>
-      <th>
-        Test prefix
-      </th>
-      {% for device_type in device_types_with_results %}
-      <th>
-        <a href="{{ device_type.link }}">{{ device_type.date }} (build {{device_type.build}})</a>
-        <br />
-        {% if device_type.last_difference %}
-        A different result was last seen in build <a href="{{ device_type.last_difference.1 }}">{{ device_type.last_difference.0 }}</a>
-        {% else %}
-        No different result has been seen
-        {% endif %}
-      </th>
-      {% endfor %}
-    </tr>
-  </thead>
-  <tbody>
-    {% for prefix, board_results in results %}
-    <tr>
-      <td>
-        {{ prefix }}
-      </td>
-      {% for board_result in board_results %}
-      <td class="{{ board_result.css_class }}">
-        {% if board_result.present %}
-        {{ board_result.pass }} / {{ board_result.total }}
-        {% endif %}
-      </td>
-      {% endfor %}
-    </tr>
-    {% endfor %}
-  </tbody>
-</table>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/pmqa_filter.html'
--- dashboard_app/templates/dashboard_app/pmqa_filter.html	2013-01-10 01:56:51 +0000
+++ dashboard_app/templates/dashboard_app/pmqa_filter.html	1970-01-01 00:00:00 +0000
@@ -1,29 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-{% load django_tables2 %}
-
-{% block extrahead %}
-{{ block.super }}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/filter-detail.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/filter-detail.js"></script>
-{% endblock %}
-
-{% block content %}
-
-<h1>PMQA results for {{ bundle_stream }} on {{ device_type }}</h1>
-{% render_table filter_table %}
-
-<p>
-  <button id="compare-button">Compare builds</button>
-  <span id="first-prompt" style="display:none">
-    Click a build to compare.
-  </span>
-  <span id="second-prompt" style="display:none">
-    Click build to compare with build <span id="p2-build">XXX</span>.
-  </span>
-  <span id="third-prompt" style="display:none">
-    Click <a href="#">here</a> to compare with build <span id="p3-build-1">XXX</span> with build <span id="p3-build-2">XXX</span>.
-  </span>
-</p>
-
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/report_detail.html'
--- dashboard_app/templates/dashboard_app/report_detail.html	2011-07-19 21:46:36 +0000
+++ dashboard_app/templates/dashboard_app/report_detail.html	1970-01-01 00:00:00 +0000
@@ -1,59 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-{% load i18n %}
-{% load stylize %}
-
-
-
-{% block extrahead %}
-{{ block.super }}
-<!--[if IE]><script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/excanvas.min.js"></script><![endif]-->
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.rpc.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.flot.min.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.dashboard.js"></script>
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/pygments.css"/>
-{% endblock %}
-
-
-{% block content %}
-{{ report.get_html|safe}}
-{% endblock %}
-
-
-{% block sidebar %}
-<h3>Basic information</h3>
-<dl>
-  <dt>Title</dt>
-  <dd>{{report.title}}</dd>
-  <dt>Author</dt>
-  <dd>{{report.author|default_if_none:"Unspecified"}}</dd>
-  <dt>Bug report URL</dt>
-  <dd>{{report.bug_report_url|default:"Unspecified"}}</dd>
-</dl>
-<h3>Third party content notice</h3>
-<p>Reports are a combination of client side programs written in JavaScript
-and sever side SQL queries. As such they are exposed to different JavaScript
-implementations. If a report does not work correctly contact the author or
-maintainer to debug the problem.</p> 
-<h3>Source Code</h3>
-<button id="show-source">Show source</button>
-<div id="report-source" style="display: none">
-  {% stylize "html" %}{{ report.get_html }}{% endstylize %}
-</div>
-<script type="text/javascript">
-  $(function() {
-    $("#report-source").dialog({ autoOpen: false, modal: true, width: "auto", title: "Source code"});
-    $("#show-source").button().click(function() {
-      $("#report-source").dialog("open");
-    });
-  });
-</script>
-{% endblock %}
-
-{% block body %}
-{% if is_iframe %}
-{{ report.get_html|safe}}
-{% else %}
-{{ block.super }}
-{% endif %}
-{% endblock %}
-

=== removed file 'dashboard_app/templates/dashboard_app/report_list.html'
--- dashboard_app/templates/dashboard_app/report_list.html	2011-07-12 02:34:12 +0000
+++ dashboard_app/templates/dashboard_app/report_list.html	1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-
-{% block content %}
-<script type="text/javascript" charset="utf-8"> 
-  $(document).ready(function() {
-    oTable = $('#reports').dataTable({
-      "bJQueryUI": true,
-      "sPaginationType": "full_numbers",
-      "aaSorting": [[0, "desc"]],
-    });
-  });
-</script> 
-<table class="demo_jui display" id="reports">
-  <thead>
-    <tr>
-      <th>{% trans "Report title" %}</th>
-      <th>{% trans "Author" %}</th>
-    </tr>
-  </thead>
-  <tbody>
-    {% for report in report_list %}
-    <tr>
-      <td><a href="{{ report.get_absolute_url }}">{{ report.title }}</a></td>
-      <td>{{ report.author|default_if_none:"<em>unspecified</em>" }}</td>
-    </tr>
-    {% endfor %}
-  </tbody>
-</table>
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/test_definition.html'
--- dashboard_app/templates/dashboard_app/test_definition.html	2013-03-25 21:39:58 +0000
+++ dashboard_app/templates/dashboard_app/test_definition.html	1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-{% load i18n %}
-{% load stylize %}
-{% load django_tables2 %}
-
-{% block extrahead %}
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}lava-server/css/demo_table_jui.css"/>
-<script type="text/javascript" src="{{ STATIC_URL }}lava-server/js/jquery.dataTables.min.js"></script> 
-{% endblock %}
-
-{% block sidebar %}
-<h3>Actions</h3>
-<ul>
-  <li><a href="{% url dashboard_app.views.test_definition %}">
-      List test definitions</a></li>
-  <li><a href="{% url dashboard_app.views.add_test_definition %}">
-      Add test definition</a></li>
-</ul>
-{% endblock %}
-
-{% block content %}
-    {% render_table testdefinition_table %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/test_result_detail.html'
--- dashboard_app/templates/dashboard_app/test_result_detail.html	2012-12-17 00:10:53 +0000
+++ dashboard_app/templates/dashboard_app/test_result_detail.html	1970-01-01 00:00:00 +0000
@@ -1,140 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-{% load i18n %}
-{% load humanize %}
-
-{% block extrahead %}
-{{ block.super }}
-<style type="text/css">
-dt { font-weight: bold }
-dd pre { margin: 0;}
-</style>
-{% endblock %}
-
-{% block content %}
-<h2>Result: {{ test_result.test_case|default:"<i>unknown test case</i>" }}</h2>
-<dl>
-  <dt>{% trans "Outcome" %}</dt>
-  <dd>
-    <img src="{{ STATIC_URL }}dashboard_app/images/icon-{{ test_result.result_code }}.png"
-         alt="{{ test_result.result_code }}" width="16" height="16" border="0"/>
-    {{ test_result.result_code }}
-  </dd>
-  <dt>{% trans "Measurement" %}</dt>
-  <dd>
-  {% if test_result.measurement != None %}
-    {{ test_result.measurement }} {{ test_result.test_case.units }}
-  {% else %}
-    <i>{% trans "no measurement taken" %}</i>
-  {% endif %}
-  </dd>
-  <dt>{% trans "Log file location" %}</dt>
-  <dd>
-    {% if test_result.filename %}
-        {% if test_result.related_attachment_available and test_result.related_attachment.is_viewable %}
-        {% with test_result.related_attachment as attachment %}
-        <a href="{{ attachment.get_view_url }}">{{ test_result.filename }}</a> line <a href="{{ attachment.get_view_url }}#L{{test_result.lineno}}">{{ test_result.lineno }}</a>
-        {% endwith %}
-        {% else %}
-            {{ test_result.filename }} line {{ test_result.lineno }}
-        {% endif %}
-    {% else %}
-        <i>{% trans "information not provided" %}</i>
-    {% endif %}
-  </dd>
-  <dt>{% trans "Message from the log file" %}</dt>
-  <dd>
-  {% if test_result.message %}
-    <pre>{{ test_result.message }}</pre>
-  {% else %}
-    <i>{% trans "information not provided" %}</i>
-  {% endif %}
-  </dd>
-  <dt>{% trans "Test started on" %}</dt>
-  <dd>
-  {% if test_result.timestamp %}
-    {{ test_result.timestamp|naturalday }}
-    {{ test_result.timestamp|time }}
-  {% else %}
-    <i>{% trans "information not provided" %}</i>
-  {% endif %}
-  </dd>
-  <dt>{% trans "Test duration" %}</dt>
-  <dd>
-  {% if test_result.duration %}
-    {# TODO need a filter for displaying this sensibly. Currently there are some rounding errors #}
-    {{ test_result.duration }}
-  {% else %}
-    <i>{% trans "information not provided" %}</i>
-  {% endif %}
-  </dd>
-</dl>
-
-<h3 id="attachments">Attachments</h3>
-
-{% include "dashboard_app/_attachments.html" with attachments=test_result.attachments %}
-
-{% if test_result.test_run.get_results.count > 1 %}
-<h3>Other results from the same test run</h3>
-<select id="other_results">
-  {% regroup test_result.test_run.get_results by test_case as test_result_group_list %}
-  {% for test_result_group in test_result_group_list %}
-  {% if test_result_group.list|length > 1 %}<optgroup label="Results for test case {{ test_result_group.grouper }}">{% endif %}
-    {% for other_test_result in test_result_group.list %}
-    <option value="{{ other_test_result.get_absolute_url }}"
-    {% if other_test_result.pk == test_result.pk %}disabled selected{% endif %}
-    >
-      Result #{{ other_test_result.relative_index }}: {{ other_test_result.get_result_display }}
-      {% if test_result_group.list|length == 1 %} from test case {{ test_result_group.grouper }}{% endif %}
-      {% if other_test_result.measurement != None %} ({{ other_test_result.measurement }}){% endif %}
-    </option>
-    {% endfor %}
-  {% if test_result_group.list|length > 1 %}</optgroup>{% endif %}
-  {% endfor %}
-</select>
-<script type="text/javascript">
-  $("#other_results").change(function (event) {
-    location.href=$(this).val();
-  });
-</script>
-{% endif %}
-
-{% endblock %}
-
-{% block sidebar %}
-<h3>Metadata</h3>
-<dl>
-  <dt>ID</dt>
-  <dd>
-    <small><span style="white-space:nowrap">{{ test_result.test_run.analyzer_assigned_uuid }}/{{ test_result.relative_index }}</span> (<a href="{{ test_result.get_permalink }}">{% trans "permalink" %}</a>)</small>
-  </dd>
-  <dt>Test Case</dt>
-  <dd>
-    {% if test_result.test_case %}
-    <b>{{ test_result.test_case }}</b>
-    {% else %}
-    <i>{% trans "unknown test case" %}</i>
-    {% endif %}
-    {% trans "from test" %} <b><a href="{{ test_result.test_run.test.get_absolute_url }}">{{ test_result.test_run.test }}</a></b>
-  </dd>
-</dl>
-<h3>Result Attributes</h3>
-{% with test_result.attributes.values as attrs %}
-<ul class="attributes">
-  {% for item in attrs|dictsort:"name" %}
-  <li>{{ item.name }}&nbsp;=&nbsp;{{ item.value }}</li>
-  {% empty %}
-  <i>none</i>
-  {% endfor %}
-</ul>
-{% endwith %}
-<h3>Run Attributes</h3>
-{% with test_result.test_run.attributes.values as attrs %}
-<ul class="attributes">
-  {% for item in attrs|dictsort:"name" %}
-  <li>{{ item.name }}&nbsp;=&nbsp;{{ item.value }}</li>
-  {% empty %}
-  <i>none</i>
-  {% endfor %}
-</ul>
-{% endwith %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/test_run_detail.html'
--- dashboard_app/templates/dashboard_app/test_run_detail.html	2012-12-11 00:55:30 +0000
+++ dashboard_app/templates/dashboard_app/test_run_detail.html	1970-01-01 00:00:00 +0000
@@ -1,106 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-
-{% load django_tables2 %}
-{% load i18n %}
-{% load humanize %}
-
-
-{% block content %}
-
-<h2>Results</h2>
-
-{% render_table test_table %}
-
-<h3>Attachments</h3>
-
-{% include "dashboard_app/_attachments.html" with attachments=test_run.attachments %}
-
-{% endblock %}
-
-
-{% block sidebar %}
-<h3>Test run details</h3>
-<dl>
-  <dt>{% trans "Test Name" %} (<abbr title="This is the identifier of the test that was invoked. A test is a collection of test cases. Test is also the smallest piece of code that can be invoked by lava-test.">?</abbr>):</dt>
-  <dd><a href="{{ test_run.test.get_absolute_url }}">{{ test_run.test.test_id }}</a>
-  </dd>
-  <dt>{% trans "Test Run UUID" %} (<abbr title="This is a globally unique identifier that was assigned by the log analyzer. Running the same test multiple times results in different values of this identifier.  The dashboard uses this identifier to refer to a particular test run. It is preserved across different LAVA installations, that is, if you pull test results (as bundles) from one system to another this identifier remains intact">?</abbr>):</dt>
-  <dd><small>{{ test_run.analyzer_assigned_uuid }}
-    (<a href="{% url dashboard_app.views.redirect_to_test_run test_run.analyzer_assigned_uuid %}">permalink</a>)</small>
-  </dd>
-  <dt>{% trans "Bundle SHA1" %} (<abbr title="This is the SHA1 hash of the bundle that contains this test run.">?</abbr>):</dt>
-  <dd><a href="{{ test_run.bundle.get_absolute_url }}"
-    ><small>{{ test_run.bundle.content_sha1 }}</small></a>
-  </dd>
-
-  <dt>{% trans "Tags" %} (<abbr title="LAVA can store tags associated with a particular test run. Tags are simple strings like &quot;project-foo-prerelase-testing&quot; or &quot;linaro-image-2011-09-27&quot;. Tags can be used by the testing effort feature to group results together.">?</abbr>):</dt>
-  <dd>
-  <ul>
-    {% for tag in test_run.tags.all %}
-    <li><code>{{ tag }}</code></li>
-    {% empty %}
-    <em>{% trans "There are no tags associated with this test run." %}</em>
-    {% endfor %}
-  </ul>
-  </dd>
-</dl>
-
-<h3>Software context</h3>
-<dl>
-  <dt>{% trans "OS Distribution:" %}</dt>
-  <dd>{{ test_run.sw_image_desc|default:"<i>Unspecified</i>" }}</dd>
-  <dt>{% trans "Software packages" %} (<abbr title="LAVA keeps track of all the software packages (such as Debian packages managed with dpkg) that were installed prior to running a test. This information can help you track down errors caused by a particular buggy dependency">?</abbr>):</dt>
-  <dd><a href="{% url dashboard_app.views.test_run_software_context test_run.bundle.bundle_stream.pathname test_run.bundle.content_sha1 test_run.analyzer_assigned_uuid %}"
-    >See all {{ test_run.packages.all.count }} software packages</a>
-  </dd>
-  <dt>{% trans "Software sources" %} (<abbr title="LAVA can track more data than just package name and version. You can track precise software information such as the version control system branch or repository, revision or tag name and more.">?</abbr>):</dt>
-  <dd><a href="{% url dashboard_app.views.test_run_software_context test_run.bundle.bundle_stream.pathname test_run.bundle.content_sha1 test_run.analyzer_assigned_uuid %}"
-    >See all {{ test_run.sources.all.count }} source references</a>
-  </dd>
-</dl>
-
-<h3>Hardware context</h3>
-<dl>
-  <dt>{% trans "Board:" %}</dt>
-  <dd>{{ test_run.get_board|default_if_none:"There are no boards associated with this test run" }}</dd>
-  <dt>{% trans "Other devices" %} (<abbr title="LAVA keeps track of the hardware that was used for testing. This can help cross-reference benchmarks and identify hardware-specific issues.">?</abbr>):</dt>
-  <dd><a
-    href="{% url dashboard_app.views.test_run_hardware_context test_run.bundle.bundle_stream.pathname test_run.bundle.content_sha1 test_run.analyzer_assigned_uuid %}"
-    >See all {{ test_run.devices.all.count }} devices</a>
-  </dd>
-</dl>
-
-<h3>Custom attributes (<abbr title="LAVA can store arbitrary key-value attributes associated with each test run (and separately, each test result)">?</abbr>)</h3>
-<ul class="attributes">
-  {% for attribute in test_run.attributes.all %}
-  <li>{{ attribute.name }} = {{ attribute.value }}</li>
-  {% empty %}
-  <i>none</i>
-  {% endfor %}
-</ul>
-
-<h3>Time stamps (<abbr title="There are three different timestamps associated with each test run. They are explained below.">?</abbr>)</h3>
-<dl>
-  <dt>{% trans "Log analyzed on" %} (<abbr title="This is the moment this that this test run's artifacts (such as log files and other output) were processed by the log analyzer. Typically the analyzer is a part of lava-test framework and test output is analyzed on right on the device so this time may not be trusted, see below for the description of &quot;time check performed&quot;">?</abbr>):</dt>
-  <dd>
-  {{ test_run.analyzer_assigned_date|naturalday }}
-  {{ test_run.analyzer_assigned_date|time }}
-  ({{ test_run.analyzer_assigned_date|timesince }} ago)
-  </dd>
-  <dt>{% trans "Time check performed" %} (<abbr title="The value &quot;no&quot; indicates that the log analyzer was not certain that the time and date is accurate.">?</abbr>):</dt>
-  <dd>{{ test_run.time_check_performed|yesno }}
-  </dd>
-  <dt>{% trans "Data imported on" %} (<abbr title="This is the moment this test run entry was created in the LAVA database. It can differ from upload date if there were any initial deserialization problems and the data was deserialized later.">?</abbr>):</dt>
-  <dd>
-  {{ test_run.import_assigned_date|naturalday }}
-  {{ test_run.import_assigned_date|time }}
-  ({{ test_run.import_assigned_date|timesince }} ago)
-  </dd>
-  <dt>{% trans "Data uploaded on" %} (<abbr title="This is the moment this data was first uploaded to LAVA (as a serialized bundle).">?</abbr>):</dt>
-  <dd>
-  {{ test_run.bundle.uploaded_on|naturalday }}
-  {{ test_run.bundle.uploaded_on|time }}
-  ({{ test_run.bundle.uploaded_on|timesince }} ago)
-  </dd>
-</dl>
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/test_run_hardware_context.html'
--- dashboard_app/templates/dashboard_app/test_run_hardware_context.html	2011-07-13 11:07:18 +0000
+++ dashboard_app/templates/dashboard_app/test_run_hardware_context.html	1970-01-01 00:00:00 +0000
@@ -1,79 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-
-{% block content %}
-<table class="demo_jui display" id="hardware_devices">
-  <thead>
-    <tr>
-      <th>Description</th>
-      <th>Device Type</th>
-      <th>Attributes</th>
-    </tr>
-  </thead>
-  <tbody>
-    {% for hardware_device in test_run.devices.all %} 
-    <tr>
-      <td>{{ hardware_device.description }}</td>
-      <td>{{ hardware_device.get_device_type_display }}</td>
-      <td>
-        <dl>
-          {% for attribute in hardware_device.attributes.all %}
-          <dt>{{ attribute.name }}</dt>
-          <dd>{{ attribute.value }}</dd>
-          {% endfor %}
-        </dl>
-      </td>
-    </tr>
-    {% endfor %}
-  </tbody>
-</table>
-<script type="text/javascript" charset="utf-8"> 
-  function fnFormatDetails(oTable, nTr) {
-    var aData = oTable.fnGetData(nTr);
-    return aData[3];
-  }
-
-  $(document).ready(function() {
-    /* Insert a 'details' column to the table */
-    var nCloneTh = document.createElement('th');
-    var nCloneTd = document.createElement('td');
-    nCloneTd.innerHTML = '<img src="{{ STATIC_URL }}dashboard_app/images/details_open.png">';
-    nCloneTd.className = "center";
-
-    $('#hardware_devices thead tr').each( function () {
-      this.insertBefore(nCloneTh, this.childNodes[0]);
-    });
-
-    $('#hardware_devices tbody tr').each( function () {
-      this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
-    });
-
-    /* Initialse DataTables, with no sorting on the 'details' column */
-    var oTable = $('#hardware_devices').dataTable({
-      aoColumnDefs: [
-        { bSortable: false, aTargets: [0] },
-        { bVisible: false, aTargets: [3] }
-      ],
-      aaSorting: [[2, 'asc']],
-      bPaginate: false,
-      bJQueryUI: true
-    });
-    /* Add event listener for opening and closing details. Note that the
-    indicator for showing which row is open is not controlled by DataTables,
-    rather it is done here */
-    $('#hardware_devices tbody td img').live('click', function () {
-      var nTr = this.parentNode.parentNode;
-      if (this.src.match('details_close')) {
-        /* This row is already open - close it */
-        this.src = "{{ STATIC_URL }}dashboard_app/images/details_open.png";
-        oTable.fnClose(nTr);
-      } else {
-        /* Open this row */
-        this.src = "{{ STATIC_URL }}dashboard_app/images/details_close.png";
-        oTable.fnOpen(nTr, fnFormatDetails(oTable, nTr), 'details');
-      }
-    });
-  });
-</script> 
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/test_run_list.html'
--- dashboard_app/templates/dashboard_app/test_run_list.html	2012-03-16 03:31:30 +0000
+++ dashboard_app/templates/dashboard_app/test_run_list.html	1970-01-01 00:00:00 +0000
@@ -1,66 +0,0 @@
-{% extends "dashboard_app/_content_with_sidebar.html" %}
-
-{% load django_tables2 %}
-{% load i18n %}
-{% load humanize %}
-
-
-{% block content %}
-<div id="master-toolbar-splice" >
-  <span
-    class="length"
-    style="float:left; display:inline-block; width:30%; text-align:left;"></span>
-  <span class="view-as">
-    <input name="radio" type="radio" id="as_bundles"/>
-    <label for="as_bundles">
-      <a
-        id="as_bundles_link"
-        href="{% url dashboard_app.views.bundle_list bundle_stream.pathname %}"
-        >{% trans "Bundles" %}</a>
-    </label>
-    <input name="radio" checked type="radio" id="as_test_runs"/>
-    <label for="as_test_runs">
-      <a
-        id="as_test_runs_link"
-        href="{% url dashboard_app.views.test_run_list bundle_stream.pathname %}"
-        >{% trans "Test Runs" %}</a>
-    </label>
-  </span>
-  <span
-    class="search"
-    style="float:right; display:inline-block; width: 30%; text-align:right"></span>
-</div>
-<script type="text/javascript" charset="utf-8"> 
-  $(document).ready(function() {
-    oTable = $('#test_runs').dataTable({
-      bJQueryUI: true,
-      sPaginationType: "full_numbers",
-      aaSorting: [[1, "desc"]],
-      iDisplayLength: 25,
-      aLengthMenu: [[10, 25, 50, -1], [10, 25, 50, "All"]],
-      sDom: 'lfr<"#master-toolbar">t<"F"ip>'
-    });
-    // Try hard to make our radio boxes behave as links
-    $("#master-toolbar-splice span.view-as").buttonset();
-    $("#master-toolbar-splice span.view-as input").change(function(event) {
-      var link = $("#" + event.target.id + "_link");
-      location.href=link.attr("href");
-    });
-    // Insane splicing below
-    $("div.dataTables_length").children().appendTo("#master-toolbar-splice span.length");
-    $("div.dataTables_filter").children().appendTo("#master-toolbar-splice span.search");
-    $("#master-toolbar-splice").children().appendTo($("#master-toolbar"));
-    $("div.dataTables_length").remove();
-    $("div.dataTables_filter").remove();
-    $("#master-toolbar-splice").remove();
-    $("#master-toolbar").addClass("ui-widget-header ui-corner-tl ui-corner-tr").css(
-      "padding", "5pt").css("text-align", "center");
-  });
-</script> 
-{% render_table test_run_table %}
-{% endblock %}
-
-
-{% block sidebar %}
-{% include "dashboard_app/_bundle_stream_sidebar.html" %}
-{% endblock %}

=== removed file 'dashboard_app/templates/dashboard_app/test_run_software_context.html'
--- dashboard_app/templates/dashboard_app/test_run_software_context.html	2011-07-12 02:34:12 +0000
+++ dashboard_app/templates/dashboard_app/test_run_software_context.html	1970-01-01 00:00:00 +0000
@@ -1,85 +0,0 @@
-{% extends "dashboard_app/_content.html" %}
-{% load i18n %}
-
-
-{% block content %}
-<div id="tabs">
-  <ul>
-    <li><a href="#tab-software-packages">Software Packages</a></li>
-    <li><a href="#tab-software-sources">Software Sources</a></li>
-  </ul>
-
-  <div id="tab-software-packages">
-    <table class="demo_jui display" id="software_packages">
-      <thead>
-        <tr>
-          <th>Name</th>
-          <th>Version</th>
-        </tr>
-      </thead>
-      <tbody>
-        {% for software_package in test_run.packages.all %}
-        <tr>
-          <td><a href="{{software_package.link_to_packages_ubuntu_com}}">{{software_package.name}}</a></td>
-          <td>{{software_package.version}}</td>
-        </tr>
-        {% endfor %}
-      </tbody>
-    </table>
-  </div>
-
-  <div id="tab-software-sources">
-    <table class="demo_jui display" id="software_sources">
-      <thead>
-        <tr>
-          <th>Project</th>
-          <th><abbr title="Version Control System">VCS</abbr></th>
-          <th>Branch</th>
-          <th>Tag or revision</th>
-        </tr>
-      </thead>
-      <tbody>
-        {% for software_source in test_run.sources.all %}
-        <tr>
-          {% if software_source.is_hosted_on_launchpad %}
-          <td><a href="{{ software_source.link_to_project }}">{{ software_source.project_name }}</a></td>
-          <td>{{software_source.branch_vcs}}</td>
-          <td><a href="{{ software_source.link_to_branch }}">{{ software_source.branch_url }}</a></td>
-          {% if software_source.is_tag_revision %}
-          <td>{{ software_source.branch_tag }}</td>
-          {% else %}
-          <td>{{ software_source.branch_revision }}</td>
-          {% endif %}
-          {% else %}
-          <td>{{software_source.project_name}}</td>
-          <td>{{software_source.branch_vcs}}</td>
-          <td>{{software_source.branch_url}}</td>
-          <td>{{software_source.branch_revision}}</td>
-          {% endif %}
-        </tr>
-        {% endfor %}
-      </tbody>
-    </table>
-  </div>
-</div>
-
-<script type="text/javascript" charset="utf-8"> 
-  $(document).ready(function() {
-    $('#software_packages').dataTable({
-      bJQueryUI: true,
-    });
-    $('#software_sources').dataTable({
-      bJQueryUI: true
-    });
-    $("#tabs").tabs({
-      cache: true,
-      show: function(event, ui) {
-        var oTable = $('div.dataTables_scrollBody>table.display', ui.panel).dataTable();
-        if ( oTable.length > 0 ) {
-          oTable.fnAdjustColumnSizing();
-        }
-      }
-    });
-  });
-</script> 
-{% endblock %}

=== removed directory 'dashboard_app/templatetags'
=== removed file 'dashboard_app/templatetags/__init__.py'
=== removed file 'dashboard_app/templatetags/call.py'
--- dashboard_app/templatetags/call.py	2011-07-22 00:29:54 +0000
+++ dashboard_app/templatetags/call.py	1970-01-01 00:00:00 +0000
@@ -1,64 +0,0 @@
-from django import template
-
-
-register = template.Library()
-
-
-class CallNode(template.Node):
-    def __init__(self, func, args, name, nodelist):
-        self.func = func
-        self.args = args
-        self.name = name
-        self.nodelist = nodelist
-
-    def __repr__(self):
-        return "<CallNode>"
-
-    def _lookup_func(self, context):
-        parts = self.func.split('.')
-        current = context[parts[0]] 
-        for part in parts[1:]:
-            if part.startswith("_"):
-                raise ValueError(
-                    "Function cannot traverse private implementation attributes")
-            current = getattr(current, part)
-        return current
-
-    def render(self, context):
-        try:
-            func = self._lookup_func(context) 
-            values = [template.Variable(arg).resolve(context) for arg in self.args]
-            context.push()
-            context[self.name] = func(*values)
-            output = self.nodelist.render(context)
-            context.pop()
-            return output
-        except Exception as ex:
-            import logging
-            logging.exception("Unable to call %s with %r: %s",
-                              self.func, self.args, ex)
-            raise
-
-def do_call(parser, token):
-    """
-    Adds a value to the context (inside of this block) for caching and easy
-    access.
-
-    For example::
-
-        {% call func 1 2 3 as result %}
-            {{ result }}
-        {% endcall %}
-    """
-    bits = list(token.split_contents())
-    if len(bits) < 2 or bits[-2] != "as":
-        raise template.TemplateSyntaxError(
-            "%r expected format is 'call func [args] [as name]'" % bits[0])
-    func = bits[1]
-    args = bits[2:-2]
-    name = bits[-1]
-    nodelist = parser.parse(('endcall',))
-    parser.delete_first_token()
-    return CallNode(func, args, name, nodelist)
-
-do_call = register.tag('call', do_call)

=== removed file 'dashboard_app/templatetags/stylize.py'
--- dashboard_app/templatetags/stylize.py	2011-05-03 18:18:34 +0000
+++ dashboard_app/templatetags/stylize.py	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-from django import template
-from pygments import highlight
-from pygments.lexers import get_lexer_by_name
-from pygments.formatters import HtmlFormatter
-
-
-register = template.Library()
-
-
-class StylizeNode(template.Node):
-
-    def __init__(self, nodelist, *varlist):
-        self.nodelist, self.vlist = (nodelist, varlist)
-
-    def render(self, context):
-        style = 'text'
-        if len(self.vlist) > 0:
-            style = template.resolve_variable(self.vlist[0], context)
-        code = self.nodelist.render(context)
-        lexer = get_lexer_by_name(style, encoding='UTF-8')
-        formatter = HtmlFormatter(cssclass="pygments")
-        return highlight(code, lexer, formatter) 
-
-
-@register.tag
-def stylize(parser, token):
-    """
-    Usage: {% stylize "language" %}...language text...{% endstylize %}
-    """
-    nodelist = parser.parse(('endstylize',))
-    parser.delete_first_token()
-    return StylizeNode(nodelist, *token.contents.split()[1:])

=== removed directory 'dashboard_app/tests'
=== removed file 'dashboard_app/tests/__init__.py'
--- dashboard_app/tests/__init__.py	2011-07-22 00:55:51 +0000
+++ dashboard_app/tests/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,55 +0,0 @@
-"""
-Package with all tests for dashboard_app
-"""
-
-import logging
-import unittest
-
-TEST_MODULES = [
-    'models.attachment',
-    'models.bundle',
-    'models.bundle_deserialization_error',
-    'models.bundle_stream',
-    'models.data_report',
-    'models.hw_device',
-    'models.named_attribute',
-    'models.sw_package',
-    'models.test',
-    'models.test_case',
-    'models.test_result',
-    'models.test_run',
-    'other.csrf',
-    'other.dashboard_api',
-    'other.dataview',
-    'other.deserialization',
-    'other.login',
-    'other.test_client',
-    'regressions.LP658917',
-    'views.bundle_stream_list_view',
-    'views.test_run_detail_view',
-    'views.test_run_list_view',
-    'views.redirects',
-]
-
-def load_tests_from_submodules(_locals):
-    """
-    Load all test classes from sub-modules as if they were here locally.
-
-    This makes django test dispatcher work correctly and allows users to
-    use the optional test identifier. The identifier has this format:
-        Application.TestClass[.test_method]
-    """
-    for name in TEST_MODULES:
-        module_name = 'dashboard_app.tests.' + name
-        try:
-            module = __import__(module_name, fromlist=[''])
-        except ImportError:
-            logging.exception("Unable to import test module %s", module_name)
-            raise
-        else:
-            for attr in dir(module):
-                obj = getattr(module, attr)
-                if isinstance(obj, type) and issubclass(obj, unittest.TestCase):
-                    _locals[attr] = obj
-
-load_tests_from_submodules(locals())

=== removed file 'dashboard_app/tests/call_helper.py'
--- dashboard_app/tests/call_helper.py	2011-05-25 11:03:30 +0000
+++ dashboard_app/tests/call_helper.py	1970-01-01 00:00:00 +0000
@@ -1,418 +0,0 @@
-#!/usr/bin/python
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Small helper module that aids in writing unit tests. It allows to
-construct objects or call functions without any arguments by looking up
-the required arguments from a helper object or from the class itself.
-"""
-
-from contextlib import contextmanager
-
-
-class CallHelper(object):
-    """
-    Helper for making easy-to-call functions that would otherwise
-    require multiple (possibly complex) arguments to call correctly.
-
-    The helper calls the provided function and takes care of any non-default
-    arguments that were not explicitly provided by getting 'good' values from a
-    helper object.
-
-    Example:
-    >>> def add(a, b): return a + b
-    >>> class dummy_values:
-    ...     a = 1
-    ...     b = 2
-    >>> add = CallHelper(add, dummy_values())
-
-    In reality the code below calls add(dummy.a, dummy.b) dummy is the
-    instance of dummy_values.
-    >>> add()
-    3
-
-    You can still call the function as it was the original
-    >>> add(5, -1)
-    4
-
-    Let's try something more complicated.
-    >>> def inc(value, increment=1):
-    ...     return value + increment
-    >>> class inc_dummy(object):
-    ...     value = 5
-    ...     increment = 2
-
-    Here the function already has a default value for one of the
-    arguments. This argument will not be obtained from the helper
-    object.
-    >>> inc = CallHelper(inc, inc_dummy())
-    >>> inc()
-    6
-
-    This is same as using DEFAULT_VALUE
-    >>> inc(increment=inc.DEFAULT_VALUE)
-    6
-
-    If you want to override this behaviour and force dummy values for
-    default argument you can use special DUMMY_VALUE value.
-    >>> inc(increment=inc.DUMMY_VALUE)
-    7
-
-    There are two special values you can use DEFAULT_VALUE and DUMMY_VALUE. Passing
-    DEFAULT_VALUE simply instructs the helper not to provide a value from the
-    defaults even if we can. Passing DUMMY_VALUE does the opposite. Having
-    both makes sense when you consider positional arguments.
-    >>> def add3(a, b, c):
-    ...     return a + b + c
-    >>> class add3_dummy(object):
-    ...     a = 1
-    ...     b = 2
-    ...     c = 3
-    >>> add3 = CallHelper(add3, add3_dummy)
-    >>> add3()
-    6
-
-    What if I want to specify the middle argument while the rest gets
-    filled with dummies? Simple, use DUMMY_VALUE positional arguments.
-    >>> add3(add3.DUMMY_VALUE, -2, add3.DUMMY_VALUE)
-    2
-
-    Another way of doing that is to use keyword arguments
-    >>> add3(b=-2)
-    2
-    """
-    DEFAULT_VALUE = object()
-    DUMMY_VALUE = object()
-
-    def __init__(self, func, dummy, dummy_preference=False):
-        """
-        Initialize call helper to wrap function `func' and supply values
-        from properties of `dummy' object.
-
-        Dummy preference defaults to False. That is, by default any
-        argument that has a default value will prefer the default value
-        rather than the dummy value obtained from dummy object.
-        """
-        if func.func_code.co_flags & 0x4:
-            raise ValueError("Functions with variable argument lists "
-                    "are not supported")
-        if func.func_code.co_flags & 0x8:
-            raise ValueError("Functions with variable keyword arguments "
-                    "are not supported")
-        self._func = func
-        self._dummy = dummy
-        self._dummy_preference = dummy_preference
-        self._args = func.func_code.co_varnames[:func.func_code.co_argcount]
-        self._args_with_defaults = dict(
-                zip(self._args[-len(func.func_defaults):] if
-                    func.func_defaults else (), func.func_defaults or ()))
-
-    def _get_dummy_for(self, arg_name):
-        """
-        Get dummy value for given argument.
-
-        Attributes are extracted from arbitrary objects
-        >>> class dummy:
-        ...     a = 1
-        >>> CallHelper(lambda x: x, dummy)._get_dummy_for('a')
-        1
-
-        Or from dictionary items (for one-liner)
-        >>> CallHelper(lambda x: x, {'a': 1})._get_dummy_for('a')
-        1
-        """
-        try:
-            return getattr(self._dummy, arg_name)
-        except AttributeError:
-            try:
-                return self._dummy[arg_name]
-            except KeyError:
-                raise ValueError("Dummy %s does not have dummy value for %s" % (
-                    self._dummy, arg_name))
-
-    def _fill_args(self, *args, **kwargs):
-        a_out = []
-        used_kwargs = set()
-        # Walk through all arguments of the original function. Ff the
-        # argument is present in `args' then use it. If we run out of
-        # positional arguments look for keyword arguments with the same
-        # name.
-        for i, arg_name in enumerate(self._args):
-            # find the argument
-            if i < len(args):
-                # positional arguments get passed as-is
-                arg = args[i]
-            elif arg_name in kwargs:
-                # keyword arguments take over
-                arg = kwargs[arg_name]
-                # also remember we got it from a keyword argument
-                used_kwargs.add(arg_name)
-            else:
-                # otherwise the function defaults kick in
-                # with a yet another fall-back to special DUMMY_VALUE value
-
-                # Note that there is a special configuration for
-                # preferring default values over dummy values.
-                if self._dummy_preference:
-                    arg = self.DUMMY_VALUE
-                else:
-                    arg = self._args_with_defaults.get(arg_name, self.DUMMY_VALUE)
-            # resolve the argument
-            if arg is self.DEFAULT_VALUE:
-                if arg_name not in self._args_with_defaults:
-                    raise ValueError("You passed DEFAULT_VALUE argument to %s "
-                            "which has no default value" % (arg_name,))
-                arg = self._args_with_defaults[arg_name]
-            elif arg is self.DUMMY_VALUE:
-                arg = self._get_dummy_for(arg_name)
-            # store the argument
-            a_out.append(arg)
-        # Now check if we have too many / not enough arguments
-        if len(a_out) != len(self._args):
-            raise TypeError("%s takes exactly %d argument, %d given" % (
-                self._func, len(self._args), len(args)))
-        # Now check keyword arguments
-        for arg_name in kwargs:
-            # Check for duplicate definitions of positional/keyword
-            # arguments
-            if arg_name in self._args and arg_name not in used_kwargs:
-                raise TypeError("%s() got multiple values for keyword "
-                        "argument '%s'" % (self._func.func_name, arg_name))
-
-            # Look for stray keyword arguments
-            if arg_name not in self._args:
-                raise TypeError("%s() got an unexpected keyword "
-                        "argument '%s'" % (self._func.func_name, arg_name))
-        # We're done
-        return a_out
-
-    def __call__(self, *args, **kwargs):
-        """
-        Call the original function passing dummy values for all
-        arguments """
-        a_out = self._fill_args(*args, **kwargs)
-        # We're done, let's call the function now! Note that we don't
-        # use kw_args as we resolve keyword arguments ourselves, this
-        # would be only useful for functions that support *args and
-        # **kwargs style variable arguments which CallHelper does not
-        # yet support.
-        return self._func(*a_out)
-
-    @contextmanager
-    def dummy_preference(self, dummy_preference=True):
-        """
-        Context manager that allows dummy values to override (be
-        preferred to) default values for unspecified arguments.
-
-        Example:
-        >>> def inc(a, b=1): return a + b
-        >>> inc = CallHelper(inc, {'b': -1})
-        >>> inc(5)
-        6
-
-        All code executed under this context manager will prefer dummy
-        values (specified as the dummy argument to the CallHelper
-        constructor) even if a default argument value is available.
-        >>> with inc.dummy_preference():
-        ...     inc(5)
-        4
-
-        This behaviour automatically reverts after the 'with' block
-        >>> inc(5)
-        6
-        """
-        old_preference = self._dummy_preference
-        try:
-            self._dummy_preference = dummy_preference
-            yield
-        finally:
-            self._dummy_preference = old_preference
-
-
-
-class ObjectFactory(CallHelper):
-    """
-    Helper class for making objects
-
-    This class allows to easily construct a dummy instances by building
-    a call_helper which will call the constructor (a rather tricky thing
-    to do).
-
-    All non-default values for the constructor will be fetched from a
-    helper object. By default you can use a convention where a nested
-    class called '_Dummy' contains all the properties you'd need to make
-    instances.
-    >>> class Person(object):
-    ...     class _Dummy:
-    ...         name = "Joe"
-    ...     def __init__(self, name):
-    ...         self.name = name
-    >>> factory = ObjectFactory(Person)
-    >>> person = factory()
-    >>> person.name
-    'Joe'
-
-    As with CallHelper you can override dummy values by passing any
-    positional or keyword arguments.
-    >>> person = factory(name="Bob")
-    >>> person.name
-    'Bob'
-
-    If you want you can store dummy values in separate class and pass it
-    along to the ObjectFactory constructor.
-    >>> class MyDummy:
-    ...     name = "Alice"
-    >>> factory = ObjectFactory(Person, MyDummy)
-    >>> person = factory()
-    >>> person.name
-    'Alice'
-
-    In addition the factory expoes the dummy values it is using via the
-    `dummy' property. This can be useful in unit tests where you don't
-    want to worry about the particular value but need to check if it can
-    be stored, retrieved, etc.
-    >>> name = factory.dummy.name
-    >>> name
-    'Alice'
-    """
-    def __init__(self, cls, dummy_cls=None):
-        """
-        Initialize ObjectFactory to create instances of class `cls'.
-        If specified, dummy values for required arguments will come from
-        instances of `dummy_cls'. Otherwise the class must have a
-        '_Dummy' nested class that will be used instead.
-        """
-        if dummy_cls is None:
-            if not hasattr(cls, '_Dummy'):
-                raise ValueError("Class %s needs to have a nested class"
-                        " called _Dummy" % (cls,))
-            dummy_cls = cls._Dummy
-        self._cls = cls
-        self._dummy = dummy_cls()
-        super(ObjectFactory, self).__init__(cls.__init__, self._dummy)
-        # remove 'self' from argument list
-        self._args = self._args[1:]
-
-    @property
-    def dummy(self):
-        """ Helper property for read-only access to dummy values """
-        return self._dummy
-
-    def __call__(self, *args, **kwargs):
-        """ Construct new object instance """
-        a_out = self._fill_args(*args, **kwargs)
-        return self._cls(*a_out)
-
-    def full_construct(self, *args, **kwargs):
-        """ Construct new object instance """
-        with self.dummy_preference():
-            a_out = self._fill_args(*args, **kwargs)
-        return self._cls(*a_out)
-
-class DummyValues(object):
-    """
-    Class for holding values used to initialize instances created with
-    ObjectFactoryMixIn
-    """
-    def __init__(self, dummy_cls):
-        self._ctor_args = {}
-        # Instantiate the class to support properties
-        dummy_obj = dummy_cls()
-        for attr_name in dir(dummy_obj):
-            if not attr_name.startswith("_"):
-                self._ctor_args[attr_name] = getattr(dummy_obj, attr_name)
-
-    def __getattr__(self, name):
-        return self._ctor_args[name]
-
-    def get_ctor_args(self):
-        return self._ctor_args
-
-
-class ObjectFactoryMixIn(object):
-    """
-    Helper mix-in for various unittest.TestCase like classes.  Allows for
-    convenient encapsulation and specification of dummy values for
-    constructing objects of any class without cluttering the code of the
-    test cases.
-
-    Example:
-    >>> class Person(object):
-    ...     def __init__(self, name):
-    ...         self.name = name
-
-    >>> class Test(ObjectFactoryMixIn):
-    ...     class Dummy:
-    ...         class Person:
-    ...             name = "Joe"
-
-    Simplest form is just to call the make() method with a class All the
-    constructor arguments will be then taken from Test.Dummy.Person
-    object (whatever it is, it's a class in this example)
-    >>> person = Test().make(Person)
-    >>> person.name
-    'Joe'
-
-    If you want to ensure that the values are stored or used by the
-    constructor properly but you don't want to hard-code 'good' values
-    in your code you can look at the dummy object that was used to
-    provide the values.
-    >>> dummy, person = Test().make_and_get_dummy(Person)
-    >>> dummy.name
-    'Joe'
-
-    So essentially the (test case) code will do something similar to
-    this:
-    >>> person.name == dummy.name
-    True
-    """
-
-    def make(self, cls, dummy_cls = None):
-        """
-        Make an object using make_and_get_dummy() and discard the dummy.
-        """
-        dummy, obj = self.make_and_get_dummy(cls, dummy_cls)
-        return obj
-
-    def make_and_get_dummy(self, cls, dummy_cls=None):
-        """
-        Make an object using the specified dummy_cls or find the
-        container of default values in the encompassing class.
-
-        class MyTest(..., ObjectFactoryMixIn):
-            class Dummy:
-                class SomeClassYouWantToCreate:
-                    ctr_arg1 = 1
-        """
-        if dummy_cls is None:
-            if hasattr(self, 'Dummy') and hasattr(self.Dummy, cls.__name__):
-                dummy_cls = getattr(self.Dummy, cls.__name__)
-            else:
-                raise ValueError("%r does not have nested class Dummy.%s" % (
-                    self.__class__, cls.__name__))
-        dummy = DummyValues(dummy_cls)
-        obj = cls(**dummy.get_ctor_args())
-        return dummy, obj
-
-
-if __name__ == '__main__':
-    import doctest
-    doctest.testmod()
-
-

=== removed file 'dashboard_app/tests/fixtures.py'
--- dashboard_app/tests/fixtures.py	2011-03-16 21:15:36 +0000
+++ dashboard_app/tests/fixtures.py	1970-01-01 00:00:00 +0000
@@ -1,138 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Helper functions for making fixtures that setup specific environment
-"""
-
-from contextlib import contextmanager
-
-from django.contrib.auth.models import (User, Group)
-
-from dashboard_app.models import (Bundle, BundleStream)
-
-
-class test_loop(object):
-    """
-    Support class that tells you something about a test crashing when
-    the actual test values depend on a loop value
-    """
-
-    def __init__(self, source):
-        self._iter = iter(source)
-        self._last = None
-
-    def __enter__(self):
-        return self
-
-    def __exit__(self, exc_type, exc_value, traceback):
-        if exc_type is not None:
-            import logging
-            logging.exception("Exception in test_loop on iteration: %r", self._last)
-
-    def __iter__(self):
-        return self
-
-    def next(self):
-        self._last = next(self._iter)
-        return self._last
-
-
-def create_bundle_stream(pathname):
-    """
-    Create, or get an existing bundle stream designated by the provided
-    pathname. The pathname is parsed and decomposed to determine the
-    user/group and slug. Users and groups are created if necessary.
-    """
-    try:
-        return BundleStream.objects.get(pathname=pathname)
-    except BundleStream.DoesNotExist:
-        user_username, group_name, slug, is_public, is_anonymous = BundleStream.parse_pathname(pathname)
-        if user_username is None and group_name is None:
-            # Here we trick a little - since the introduction of the
-            # django-restricted-resource each object has a principal
-            # owner - either a user or a group. This information can be
-            # conveyed from the pathname _except_ for anonymous streams
-            # that are a remnant of the past. For those streams we just
-            # create a dummy user.
-            user_username = "anonymous-stream-owner"
-        if user_username is not None:
-            user = User.objects.get_or_create(username=user_username)[0]
-        else:
-            user = None
-        if group_name is not None:
-            group = Group.objects.get_or_create(name=group_name)[0]
-        else:
-            group = None
-        bundle_stream = BundleStream.objects.create(
-            user=user, group=group, slug=slug,
-            is_public=is_public, is_anonymous=is_anonymous)
-        bundle_stream.save()
-        return bundle_stream
-
-
-def create_bundle(pathname, content, content_filename):
-    """"
-    Create bundle with the specified content and content_filename and
-    place it in a bundle stream designated by the specified pathname.
-    Bundle stream is created if required.
-    """
-    return Bundle.objects.create_with_content(
-        bundle_stream=create_bundle_stream(pathname),
-        uploaded_by=None,
-        content_filename=content_filename,
-        content=content)
-
-
-@contextmanager
-def created_bundle_streams(pathnames):
-    """
-    Helper context manager that creates bundle streams according to
-    specification.
-
-    `pathnames`: list of pathnames to create
-        List of values to create_bundle_stream()
-
-    yields: list of BundleStream
-        List of created bundle stream objects
-    """
-    bundle_streams = []
-    for pathname in pathnames:
-        bundle_streams.append(create_bundle_stream(pathname))
-    yield bundle_streams
-
-
-@contextmanager
-def created_bundles(spec):
-    """
-    Helper context manager that creates bundles according to specification
-
-    spec is a list of 3-element tuples:
-        pathname: string, bundle stream pathname (all variants supported)
-        content: string, text of the bundle
-        content_filename: string
-
-    yields: list of created bundles
-    """
-    bundles = []
-    for pathname, content_filename, content in spec:
-        bundles.append(
-            create_bundle(pathname, content, content_filename))
-    yield bundles
-    for bundle in bundles:
-        bundle.delete_files()

=== removed file 'dashboard_app/tests/import_prohibitor.py'
--- dashboard_app/tests/import_prohibitor.py	2011-05-25 11:03:30 +0000
+++ dashboard_app/tests/import_prohibitor.py	1970-01-01 00:00:00 +0000
@@ -1,144 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Helper module with ImportMockingTestCase class
-"""
-
-import sys
-import gc
-import types
-
-from unittest import TestCase
-
-
-class _ImportProhibitorHook(object):
-
-    def __init__(self):
-        self.prohibited = set()
-
-    def disallow(self, fullname):
-        self.prohibited.add(fullname)
-
-    def find_module(self, fullname, path=None):
-        if fullname in self.prohibited:
-            return self
-
-    def load_module(self, fullname):
-        raise ImportError("Importing module %s is prohibited" % (fullname,))
-
-
-class ImportMockingTestCase(TestCase):
-
-    def setUp(self):
-        super(ImportMockingTestCase, self).setUp()
-        self._hook = _ImportProhibitorHook()
-        self._hidden_modules = {}
-
-    def tearDown(self):
-        self._restore_hidden()
-        super(ImportMockingTestCase, self).tearDown()
-
-    def prohibit_importing(self, fullname):
-        """
-        Disallow importing of module `fullname'.
-        During the rest of the test case any attempts to import
-        this module will raise ImportError.
-        """
-        self._hook.disallow(fullname)
-
-    def _get_referring_modules(self, obj):
-        """
-        Find all modules that *directly* refer to object `obj'
-        """
-        for ref_obj in gc.get_referrers(obj):
-            if isinstance(ref_obj, dict) and '__name__' in ref_obj:
-                for mod in gc.get_referrers(ref_obj):
-                    if isinstance(mod, types.ModuleType):
-                        yield mod.__name__
-
-    def mock_imports(self, reload_list=None):
-        """
-        Make prohibit_importing() work by hiding and importing
-        again all the modules that depended on an imported
-        prohibited module.
-
-        This does _NOT_ work 100% reliably as it only finds modules that
-        directly imported one of the prohibited modules AND it depends
-        on being able to safely reimport them. If autodetection fails
-        pass a module, or a list of modules to reimport.
-
-        The side effects of this function last until the end of the test
-        case, in other words, until tearDown() is implicitly called.
-        """
-        to_reload = set()
-        if reload_list is not None:
-            if isinstance(reload_list, basestring):
-                reload_list = [reload_list]
-            to_reload.update(reload_list)
-        to_hide = set()
-        to_hide.update(to_reload)
-
-        # For all the things we want to disallow
-        for fullname in self._hook.prohibited:
-            # Modules not yet loaded do not require any actions
-            if fullname not in sys.modules:
-                continue
-            # Loaded modules must be hidden
-            to_hide.add(fullname)
-            # And all of their dependencies must be reloaded
-            module = sys.modules[fullname]
-            for related_fullname in self._get_referring_modules(module):
-                if hasattr(sys.modules[related_fullname],
-                        '__inhibit_protect__'):
-                    continue
-                to_hide.add(related_fullname)
-                to_reload.add(related_fullname)
-        # Install our meta-import hook
-        sys.meta_path.append(self._hook)
-        # Hide modules
-        for fullname in to_hide:
-            self._hide(fullname)
-        # Reload modules
-        for fullname in to_reload:
-            self._reload(fullname)
-
-    def _hide(self, fullname):
-        self._hidden_modules[fullname] = sys.modules[fullname]
-        del sys.modules[fullname]
-
-    def _reload(self, fullname):
-        # Only reload if it is not loaded already
-        # This might seem crazy but it is required because
-        # we reload a sequence of modules that might import
-        # things themselves.
-        # Example:
-        #   1) to_reload: a, b; to_hide: a, b
-        #      original a and b are now hidden
-        #   2) _reload('a')
-        #   3) we __import__('a')
-        #   4) a imports b
-        #   5) _reload('b')
-        #   6) 'b' is already imported so we don't do anything about it
-        if fullname not in sys.modules:
-            __import__(fullname, fromlist=[''])
-
-    def _restore_hidden(self):
-        if self._hook in sys.meta_path:
-            sys.meta_path.remove(self._hook)
-        sys.modules.update(self._hidden_modules)

=== removed directory 'dashboard_app/tests/models'
=== removed file 'dashboard_app/tests/models/__init__.py'
=== removed file 'dashboard_app/tests/models/attachment.py'
--- dashboard_app/tests/models/attachment.py	2011-05-25 13:22:07 +0000
+++ dashboard_app/tests/models/attachment.py	1970-01-01 00:00:00 +0000
@@ -1,90 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the Attachment model
-"""
-from django.contrib.contenttypes import generic
-from django.core.files.base import ContentFile
-from django.db import models
-from django.test import TestCase
-
-from dashboard_app.models import Attachment
-
-
-class ModelWithAttachments(models.Model):
-    """
-    Test model that uses attachments
-    """
-    attachments = generic.GenericRelation(Attachment)
-
-    class Meta:
-        # This requires a bit of explanation. Traditionally we could add new
-        # models inside test modules and they would be picked up by django and
-        # synchronized (created in the test database) as a part of the test
-        # provisioning process.
-
-        # Since we started using south, synchronization is no longer occurring
-        # for the 'dashboard_app' application. This caused some test failures
-        # such as any tests that depended on the existence of this model.
-
-        # As a workaround we artificially "stick" this model into the only
-        # application that we can count on to exist _and_ not use south as well
-        # -- that is south itself.
-
-        # This way the test model gets synchronized when south is synchronized
-        # and all the test code below works as expected.
-        app_label = "south"
-
-
-class AttachmentTestCase(TestCase):
-    _CONTENT = "text"
-    _FILENAME = "filename"
-
-    def setUp(self):
-        self.obj = ModelWithAttachments.objects.create()
-
-    def test_attachment_can_be_added_to_models(self):
-        attachment = self.obj.attachments.create(
-            content_filename = self._FILENAME, content=None)
-        self.assertEqual(attachment.content_object, self.obj)
-
-    def test_attachment_can_be_accessed_via_model(self):
-        self.obj.attachments.create(
-            content_filename = self._FILENAME, content=None)
-        self.assertEqual(self.obj.attachments.count(), 1)
-        retrieved_attachment = self.obj.attachments.all()[0]
-        self.assertEqual(retrieved_attachment.content_object, self.obj)
-
-    def test_attachment_stores_data(self):
-        attachment = self.obj.attachments.create(
-            content_filename = self._FILENAME, content=None)
-        attachment.content.save(
-            self._FILENAME,
-            ContentFile(self._CONTENT))
-        self.assertEqual(attachment.content_filename, self._FILENAME)
-        attachment.content.open()
-        try:
-            self.assertEqual(attachment.content.read(), self._CONTENT)
-        finally:
-            attachment.content.close()
-            attachment.content.delete(save=False)
-
-    def test_unicode(self):
-        obj = Attachment(content_filename="test.json")
-        self.assertEqual(unicode(obj), "test.json")

=== removed file 'dashboard_app/tests/models/bundle.py'
--- dashboard_app/tests/models/bundle.py	2011-09-26 12:55:16 +0000
+++ dashboard_app/tests/models/bundle.py	1970-01-01 00:00:00 +0000
@@ -1,120 +0,0 @@
-"""
-Tests for the Bundle model
-"""
-import hashlib
-
-from django.core.files.base import ContentFile
-from django.test import TestCase
-from django_testscenarios.ubertest import TestCaseWithScenarios
-from mocker import Mocker, expect
-
-from dashboard_app.tests import fixtures
-from dashboard_app.models import (
-    Bundle,
-    BundleDeserializationError,
-    BundleStream,
-)
-from dashboard_app.tests.call_helper import ObjectFactoryMixIn
-
-
-class BundleTests(TestCase, ObjectFactoryMixIn):
-
-    class Dummy:
-        class Bundle:
-            @property
-            def bundle_stream(self):
-                from django.contrib.auth.models import User
-                user = User.objects.get_or_create(username="dummy_user")[0]
-                return BundleStream.objects.get_or_create(slug="foobar", user=user)[0]
-            uploaded_by = None
-            content = ContentFile("file content")
-            content_filename = "file.txt"
-
-    def test_construction(self):
-        dummy, bundle = self.make_and_get_dummy(Bundle)
-        bundle.content.save(bundle.content_filename, dummy.content)
-        # reset the dummy content file pointer for subsequent tests
-        dummy.content.seek(0)
-        content = dummy.content.read()
-
-        bundle.save()
-        try:
-            self.assertEqual(bundle.bundle_stream, dummy.bundle_stream)
-            self.assertEqual(bundle.uploaded_by, dummy.uploaded_by)
-            #self.assertEqual(bundle.uploaded_on, mocked_value_of_time.now)
-            self.assertEqual(bundle.is_deserialized, False)
-            bundle.content.open()
-            self.assertEqual(bundle.content.read(), content)
-            bundle.content.close()
-            self.assertEqual(bundle.content_sha1,
-                    hashlib.sha1(content).hexdigest())
-            self.assertEqual(bundle.content_filename,
-                    dummy.content_filename)
-        finally:
-            bundle.delete_files()
-
-    def test_unicode(self):
-        obj = Bundle(content_filename="file.json", pk=1)
-        self.assertEqual(unicode(obj), u"Bundle None")
-
-
-class BundleDeserializationTests(TestCaseWithScenarios):
-
-    scenarios = [
-        ('dummy_import_failure', {
-            'pathname': '/public/personal/admin/',
-            'is_public': 'true',
-            'content': 'bogus',
-            'content_filename': 'test1.json',
-        }),
-    ]
-
-    def setUp(self):
-        super(BundleDeserializationTests, self).setUp()
-        self.bundle = fixtures.create_bundle(
-            self.pathname, self.content, self.content_filename)
-        self.mocker = Mocker()
-
-    def tearDown(self):
-        self.bundle.delete_files()
-        self.mocker.restore()
-        self.mocker.verify()
-        super(BundleDeserializationTests, self).tearDown()
-
-    def test_deserialize_failure_leaves_trace(self):
-        mock = self.mocker.patch(self.bundle)
-        expect(mock._do_deserialize(False)).throw(Exception("boom"))
-        self.mocker.replay()
-        self.bundle.deserialize(False)
-        self.assertFalse(self.bundle.is_deserialized)
-        self.assertEqual(self.bundle.deserialization_error.error_message, "boom")
-
-    def test_deserialize_ignores_deserialized_bundles(self):
-        # just reply as we're not using mocker in this test case 
-        self.mocker.replay()
-        self.bundle.is_deserialized = True
-        self.bundle.deserialize(False)
-        self.assertTrue(self.bundle.is_deserialized)
-
-    def test_deserialize_sets_is_serialized_on_success(self):
-        mock = self.mocker.patch(self.bundle)
-        expect(mock._do_deserialize(False))
-        self.mocker.replay()
-        self.bundle.deserialize(False)
-        self.assertTrue(self.bundle.is_deserialized)
-
-    def test_deserialize_clears_old_error_on_success(self):
-        BundleDeserializationError.objects.create(
-            bundle = self.bundle,
-            error_message="not important").save()
-        mock = self.mocker.patch(self.bundle)
-        expect(mock._do_deserialize(False))
-        self.mocker.replay()
-        self.bundle.deserialize(False)
-        # note we cannot check for self.bundle.deserialization_error
-        # directly due to the way django handles operations that affect
-        # existing instances (it does not touch them like storm would
-        # IIRC).
-        self.assertRaises(
-            BundleDeserializationError.DoesNotExist,
-            BundleDeserializationError.objects.get, bundle=self.bundle)

=== removed file 'dashboard_app/tests/models/bundle_deserialization_error.py'
--- dashboard_app/tests/models/bundle_deserialization_error.py	2010-10-14 09:08:24 +0000
+++ dashboard_app/tests/models/bundle_deserialization_error.py	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the BundleDeserializationError model
-"""
-
-from django.test import TestCase
-
-from dashboard_app.models import BundleDeserializationError
-
-
-class BundleDeserializationErrorTests(TestCase):
-
-    def test_unicode(self):
-        obj = BundleDeserializationError(error_message="boom")
-        self.assertEqual(unicode(obj), u"boom")

=== removed file 'dashboard_app/tests/models/bundle_stream.py'
--- dashboard_app/tests/models/bundle_stream.py	2012-03-15 03:08:00 +0000
+++ dashboard_app/tests/models/bundle_stream.py	1970-01-01 00:00:00 +0000
@@ -1,151 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the BundleStream model
-"""
-
-from django.contrib.auth.models import User, Group
-from django.db import IntegrityError
-from django_testscenarios.ubertest import TestCase, TestCaseWithScenarios
-
-from dashboard_app.models import BundleStream
-from dashboard_app.tests import fixtures
-
-
-class BundleStreamTests(TestCaseWithScenarios):
-
-    _NAME = "name"
-    _SLUG = "slug"
-    _GROUPNAME = "group"
-    _USERNAME = "user"
-
-    scenarios = [
-        ('anonymous-no-slug', {
-            'pathname': '/anonymous/',
-            'is_public': "true",
-            'is_anonymous': "true",
-            'username': "user",
-        }),
-        ('anonymous-with-slug', {
-            'name': _NAME,
-            'slug': _SLUG,
-            'is_public': "true",
-            'is_anonymous': "true",
-            'pathname': '/anonymous/slug/',
-            'username': "user",
-        }),
-        ('personal-no-slug', {
-            'username': _USERNAME,
-            'pathname': '/private/personal/user/',
-        }),
-        ('personal-with-slug', {
-            'username': _USERNAME,
-            'name': _NAME,
-            'slug': _SLUG,
-            'pathname': '/private/personal/user/slug/',
-        }),
-        ('team-no-slug', {
-            'groupname': _GROUPNAME,
-            'pathname': '/private/team/group/',
-        }),
-        ('team-with-slug', {
-            'groupname': _GROUPNAME,
-            'name': _NAME,
-            'slug': _SLUG,
-            'pathname': '/private/team/group/slug/',
-        }),
-    ]
-
-    groupname = None
-    username = None
-    group = None
-    user = None
-    name = ''
-    slug = ''
-    is_public = 0
-    is_anonymous = 0
-
-    def setUp(self):
-        super(BundleStreamTests, self).setUp()
-        if self.username is not None:
-            self.user = User.objects.create(username='user')
-        if self.groupname is not None:
-            self.group = Group.objects.create(name='group')
-
-    def test_creation(self):
-        bundle_stream = BundleStream.objects.create(
-            user=self.user, group=self.group, name=self.name, slug=self.slug)
-        bundle_stream.save()
-        self.assertEqual(bundle_stream.user, self.user)
-        self.assertEqual(bundle_stream.group, self.group)
-        self.assertEqual(bundle_stream.name, self.name)
-        self.assertEqual(bundle_stream.slug, self.slug)
-
-    def test_team_named_stream(self):
-        bundle_stream = BundleStream.objects.create(
-            user=self.user, group=self.group, name=self.name, slug=self.slug, 
-            is_anonymous=self.is_anonymous, is_public=self.is_public)
-        bundle_stream.save()
-        self.assertEqual(bundle_stream.pathname, self.pathname)
-
-    def test_pathname_uniqueness(self):
-        bundle_stream = BundleStream.objects.create(
-            user=self.user, group=self.group, name=self.name, slug=self.slug)
-        bundle_stream.save()
-        self.assertRaises(
-            IntegrityError,
-            BundleStream.objects.create,
-            user=self.user, group=self.group, slug=self.slug,
-            name=self.name
-        )
-
-    def test_pathname_update(self):
-        bundle_stream = BundleStream.objects.create(
-            user=self.user, group=self.group, name=self.name, slug=self.slug)
-        bundle_stream.save()
-        old_pathname = bundle_stream.pathname
-        bundle_stream.slug += "-changed"
-        bundle_stream.save()
-        self.assertNotEqual(bundle_stream.pathname, old_pathname)
-        self.assertEqual(
-            bundle_stream.pathname,
-            bundle_stream._calc_pathname()
-        )
-
-    def test_unicode(self):
-        obj = BundleStream(pathname=self.pathname)
-        self.assertEqual(unicode(obj), self.pathname)
-
-
-class BundleStreamPermissionTests(TestCase):
-
-    def test_can_upload_to_anonymous(self):
-        user = User.objects.create(username='user')
-        bundle_stream = fixtures.create_bundle_stream("/anonymous/")
-        self.assertTrue(bundle_stream.can_upload(user))
-
-    def test_can_upload_to_owned_stream(self):
-        bundle_stream = fixtures.create_bundle_stream("/public/personal/owner/")
-        user = User.objects.get(username='owner')
-        self.assertTrue(bundle_stream.can_upload(user))
-
-    def test_can_upload_to_other_stream(self):
-        bundle_stream = fixtures.create_bundle_stream("/public/personal/owner/")
-        user = User.objects.create(username='non-owner')
-        self.assertFalse(bundle_stream.can_upload(user))

=== removed file 'dashboard_app/tests/models/data_report.py'
--- dashboard_app/tests/models/data_report.py	2011-06-23 10:09:42 +0000
+++ dashboard_app/tests/models/data_report.py	1970-01-01 00:00:00 +0000
@@ -1,49 +0,0 @@
-# Copyright (C) 2010, 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for data reports
-"""
-
-from django.core.urlresolvers import reverse
-from django_testscenarios.ubertest import TestCase
-from mocker import Mocker, expect
-
-from dashboard_app.models import DataReport
-
-
-class DataReportTests(TestCase):
-
-    def test_template_context_has_API_URL(self):
-        mocker = Mocker()
-        report = mocker.patch(DataReport())
-        expect(report._get_raw_html()).result("{{API_URL}}")
-        with mocker:
-            observed = report.get_html()
-            expected = reverse("dashboard_app.views.dashboard_xml_rpc_handler")
-            self.assertEqual(observed, expected)
-
-    def test_template_context_does_not_have_RequestContext_things(self):
-        mocker = Mocker()
-        report = mocker.patch(DataReport())
-        expect(report._get_raw_html()).result("{{MEDIA_URL}}")
-        with mocker:
-            observed = report.get_html()
-            expected = ""
-            self.assertEqual(observed, expected)
-

=== removed file 'dashboard_app/tests/models/hw_device.py'
--- dashboard_app/tests/models/hw_device.py	2011-06-17 01:33:55 +0000
+++ dashboard_app/tests/models/hw_device.py	1970-01-01 00:00:00 +0000
@@ -1,44 +0,0 @@
-"""
-Tests for the HardwareDevice model
-"""
-
-from django.db import IntegrityError
-from django.test import TestCase
-
-from dashboard_app.models import HardwareDevice
-from dashboard_app.tests.call_helper import ObjectFactoryMixIn
-
-
-class HardwareDeviceTestCase(TestCase, ObjectFactoryMixIn):
-
-    class Dummy:
-        class HardwareDevice:
-            device_type = 'device.cpu'
-            description = 'some cpu'
-
-    def test_creation(self):
-        dummy, hw_device = self.make_and_get_dummy(HardwareDevice)
-        hw_device.save()
-        self.assertEqual(hw_device.device_type, dummy.device_type)
-        self.assertEqual(hw_device.description, dummy.description)
-
-    def test_attributes(self):
-        hw_device = self.make(HardwareDevice)
-        hw_device.save()
-        hw_device.attributes.create(name="connection-bus", value="usb")
-        self.assertEqual(hw_device.attributes.count(), 1)
-        attr = hw_device.attributes.get()
-        self.assertEqual(attr.name, "connection-bus")
-        self.assertEqual(attr.value, "usb")
-
-    def test_attributes_uniqueness(self):
-        hw_device = self.make(HardwareDevice)
-        hw_device.save()
-        hw_device.attributes.create(name="name", value="value")
-        self.assertRaises(IntegrityError, hw_device.attributes.create,
-                name="name", value="value")
-
-    def test_unicode(self):
-        obj = HardwareDevice(description=u"ARM SoC")
-        self.assertEqual(unicode(obj), u"ARM SoC")
-

=== removed file 'dashboard_app/tests/models/named_attribute.py'
--- dashboard_app/tests/models/named_attribute.py	2010-10-11 13:04:02 +0000
+++ dashboard_app/tests/models/named_attribute.py	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the NamedAttribute model
-"""
-
-from django.test import TestCase
-
-from dashboard_app.models import NamedAttribute
-
-
-class NamedAttributeTests(TestCase):
-
-    def test_unicode(self):
-        obj = NamedAttribute(name="name", value="value")
-        self.assertEqual(unicode(obj), u"name: value")

=== removed file 'dashboard_app/tests/models/sw_package.py'
--- dashboard_app/tests/models/sw_package.py	2011-06-17 01:33:55 +0000
+++ dashboard_app/tests/models/sw_package.py	1970-01-01 00:00:00 +0000
@@ -1,41 +0,0 @@
-"""
-Test for the SoftwarePackage model
-"""
-
-from django.db import IntegrityError
-from django.test import TestCase
-
-from dashboard_app.models import SoftwarePackage
-from dashboard_app.tests.call_helper import ObjectFactoryMixIn
-
-
-class SoftwarePackageTestCase(TestCase, ObjectFactoryMixIn):
-
-    class Dummy:
-        class SoftwarePackage:
-            name = 'libfoo'
-            version = '1.2.0'
-
-    def test_creation_1(self):
-        dummy, sw_package = self.make_and_get_dummy(SoftwarePackage)
-        sw_package.save()
-        self.assertEqual(sw_package.name, dummy.name)
-        self.assertEqual(sw_package.version, dummy.version)
-
-    def test_LP744922(self):
-        """
-        Regression test for https://bugs.launchpad.net/launch-control/+bug/744922
-        """
-        sw_package = SoftwarePackage.objects.create(name='foo', version='x' * 33)
-        sw_package.save()
-        self.assertEqual(len(sw_package.version), 33)
-
-    def test_uniqueness(self):
-        pkg1 = self.make(SoftwarePackage)
-        pkg1.save()
-        pkg2 = self.make(SoftwarePackage)
-        self.assertRaises(IntegrityError, pkg2.save)
-
-    def test_unicode(self):
-        obj = SoftwarePackage(name="foo", version="1.2")
-        self.assertEqual(unicode(obj), u"foo 1.2")

=== removed file 'dashboard_app/tests/models/test.py'
--- dashboard_app/tests/models/test.py	2011-05-23 17:02:43 +0000
+++ dashboard_app/tests/models/test.py	1970-01-01 00:00:00 +0000
@@ -1,69 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the Test model
-"""
-
-from django.db import IntegrityError
-from django.test import TestCase
-from django_testscenarios.ubertest import TestCaseWithScenarios
-
-from dashboard_app.models import Test
-
-
-class TestConstructionTests(TestCaseWithScenarios):
-
-    scenarios = [
-        ('simple1', {
-            'test_id': 'org.linaro.testheads.android',
-            'name': "Android test suite"}),
-        ('simple2', {
-            'test_id': 'org.mozilla.unit-tests',
-            'name': "Mozilla unit test collection"})
-    ]
-
-    def test_construction(self):
-        test = Test(test_id = self.test_id, name = self.name)
-        test.save()
-        self.assertEqual(test.test_id, self.test_id)
-        self.assertEqual(test.name, self.name)
-
-    def test_test_id_uniqueness(self):
-        test = Test(test_id = self.test_id, name = self.name)
-        test.save()
-        test2 = Test(test_id = self.test_id)
-        self.assertRaises(IntegrityError, test2.save)
-
-
-class TestUnicodeTests(TestCase):
-
-    def test_unicode_for_test_with_id(self):
-        """Test.test_id used when Test.name is not set"""
-        obj = Test(test_id="org.some_test")
-        self.assertEqual(unicode(obj), "org.some_test")
-
-    def test_unicode_for_test_with_name(self):
-        """Test.name used when available"""
-        obj = Test(name="Some Test")
-        self.assertEqual(unicode(obj), "Some Test")
-
-    def test_unicode_for_test_with_id_and_name(self):
-        """Test.name takes precedence over Test.test_id"""
-        obj = Test(name="Some Test", test_id="org.some_test")
-        self.assertEqual(unicode(obj), "Some Test")

=== removed file 'dashboard_app/tests/models/test_case.py'
--- dashboard_app/tests/models/test_case.py	2011-05-23 17:02:43 +0000
+++ dashboard_app/tests/models/test_case.py	1970-01-01 00:00:00 +0000
@@ -1,76 +0,0 @@
-"""
-Test for the TestCase model
-"""
-
-from django.db import IntegrityError
-from django.test import TestCase
-from django_testscenarios.ubertest import TestCaseWithScenarios
-
-from dashboard_app.models import (
-    Test,
-    TestCase as TestCaseModel,
-)
-
-
-class TestCaseConstructionTests(TestCaseWithScenarios):
-
-    scenarios = [
-        ('simple1', {
-            'test_id': 'org.linaro.testheads.android',
-            'test_case_id': 'testcase1',
-            'name': "Boot test",
-            'units': '',
-        }),
-        ('simple2', {
-            'test_id': 'org.mozilla.unit-tests',
-            'test_case_id': 'testcase125',
-            'name': "Rendering test",
-            'units': 'frames/s',
-        }),
-    ]
-
-    def setUp(self):
-        super(TestCaseConstructionTests, self).setUp()
-        self.test = Test(test_id=self.test_id)
-        self.test.save()
-
-    def test_construction(self):
-        test_case = TestCaseModel(
-            test = self.test,
-            test_case_id = self.test_case_id,
-            name = self.name,
-            units = self.units
-        )
-        test_case.save()
-        self.assertEqual(self.name, test_case.name)
-        self.assertEqual(self.test_case_id, test_case.test_case_id)
-        self.assertEqual(self.name, test_case.name)
-        self.assertEqual(self.units, test_case.units)
-
-    def test_test_and_test_case_id_uniqueness(self):
-        test_case = TestCaseModel(
-            test = self.test,
-            test_case_id = self.test_case_id)
-        test_case.save()
-        test_case2 = TestCaseModel(
-            test = self.test,
-            test_case_id = self.test_case_id)
-        self.assertRaises(IntegrityError, test_case2.save)
-
-
-class TestCaseUnicodeTests(TestCase):
-
-    def test_test_case_with_id(self):
-        """TestCase.test_case_id used when TestCase.name is not set"""
-        obj = TestCaseModel(test_case_id="test123")
-        self.assertEqual(unicode(obj), "test123")
-
-    def test_test_case_with_name(self):
-        """TestCase.name used when available"""
-        obj = TestCaseModel(name="Test 123")
-        self.assertEqual(unicode(obj), "Test 123")
-
-    def test_test_case_with_id_and_name(self):
-        """TestCase.name takes precedence over TestCase.test_case_id"""
-        obj = TestCaseModel(name="Test 123", test_case_id="test123")
-        self.assertEqual(unicode(obj), "Test 123")

=== removed file 'dashboard_app/tests/models/test_result.py'
--- dashboard_app/tests/models/test_result.py	2011-05-23 17:02:43 +0000
+++ dashboard_app/tests/models/test_result.py	1970-01-01 00:00:00 +0000
@@ -1,77 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the TestResult model
-"""
-import datetime
-
-from django_testscenarios.ubertest import TestCase, TestCaseWithScenarios
-
-from dashboard_app.models import TestRun, TestResult
-
-
-class TestResultDurationTests(TestCaseWithScenarios):
-
-    scenarios = [
-        ('none_is_null', {
-            'duration': None,
-            'microseconds': None,
-        }),
-        ('0_is_0', {
-            'duration': datetime.timedelta(days=0, seconds=0, microseconds=0),
-            'microseconds': 0,
-        }),
-        ('microseconds_are_just_microseconds', {
-            'duration': datetime.timedelta(microseconds=1),
-            'microseconds': 1,
-        }),
-        ('second_is_10e6_microseconds', {
-            'duration': datetime.timedelta(seconds=1),
-            'microseconds': 10**6,
-        }),
-        ('day_is_24_times_60_times_60_times_10e6_microseconds', {
-            'duration': datetime.timedelta(days=1),
-            'microseconds': 24 * 60 * 60 * 10 ** 6,
-        }),
-        ('microseconds_seconds_and_days_are_used', {
-            'duration': datetime.timedelta(days=1, seconds=1, microseconds=1),
-            'microseconds': (
-                24 * 60 * 60 * (10 ** 6) +
-                10 ** 6 +
-                1)
-        }),
-    ]
-
-    def test_duration_to_microseconds(self):
-        obj = TestResult()
-        obj.duration = self.duration
-        self.assertEqual(self.microseconds, obj.microseconds)
-
-    def test_microseconds_to_duration(self):
-        obj = TestResult()
-        obj.microseconds = self.microseconds
-        self.assertEqual(self.duration, obj.duration)
-
-
-class TestResultUnicodeTests(TestCase):
-
-    def test_test_result__pass(self):
-        test_run = TestRun(analyzer_assigned_uuid="00000000-0000-0000-0000-000000000004")
-        test_result = TestResult(test_run=test_run, relative_index=1)
-        self.assertIn("00000000-0000-0000-0000-000000000004/1", unicode(test_result))

=== removed file 'dashboard_app/tests/models/test_run.py'
--- dashboard_app/tests/models/test_run.py	2011-05-23 17:02:43 +0000
+++ dashboard_app/tests/models/test_run.py	1970-01-01 00:00:00 +0000
@@ -1,62 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the TestRun model
-"""
-
-import datetime
-
-from django_testscenarios.ubertest import TestCase
-
-from dashboard_app.tests import fixtures
-from dashboard_app.models import Test, TestRun
-
-
-class TestRunTests(TestCase):
-
-    _TEST_ID = "test_id"
-    _BUNDLE_PATHNAME = "/anonymous/"
-    _BUNDLE_CONTENT_FILENAME = "bundle.txt"
-    _BUNDLE_CONTENT = "content not relevant"
-
-    def test_construction(self):
-        test = Test.objects.create(test_id=self._TEST_ID)
-        analyzer_assigned_uuid = '9695b58e-bfe9-11df-a9a4-002163936223'
-        analyzer_assigned_date = datetime.datetime(2010, 9, 14, 12, 20, 00)
-        time_check_performed = False
-        spec = [(self._BUNDLE_PATHNAME, self._BUNDLE_CONTENT_FILENAME,
-                self._BUNDLE_CONTENT)]
-        with fixtures.created_bundles(spec) as bundles:
-            test_run = TestRun(
-                bundle = bundles[0],
-                test = test,
-                time_check_performed=time_check_performed,
-                analyzer_assigned_uuid = analyzer_assigned_uuid,
-                analyzer_assigned_date = analyzer_assigned_date,
-            )
-            test_run.save()
-            self.assertEqual(test_run.bundle, bundles[0])
-            self.assertEqual(test_run.time_check_performed, time_check_performed)
-            self.assertEqual(test_run.test, test)
-            self.assertEqual(test_run.analyzer_assigned_uuid,
-                             analyzer_assigned_uuid)
-
-    def test_unicode(self):
-        obj = TestRun(analyzer_assigned_uuid="0" * 16)
-        self.assertIn(obj.analyzer_assigned_uuid, unicode(obj))

=== removed directory 'dashboard_app/tests/other'
=== removed file 'dashboard_app/tests/other/__init__.py'
=== removed file 'dashboard_app/tests/other/csrf.py'
--- dashboard_app/tests/other/csrf.py	2012-08-28 01:45:04 +0000
+++ dashboard_app/tests/other/csrf.py	1970-01-01 00:00:00 +0000
@@ -1,88 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for Cross-Site Request Forgery middleware configuration
-"""
-import xmlrpclib
-
-import django
-from django import forms
-from django.conf.urls.defaults import patterns, url
-from django.core.urlresolvers import reverse
-from django.http import HttpResponse
-from django.template import Template, RequestContext
-
-from dashboard_app.tests.utils import CSRFTestCase
-from lava_server import urls
-
-
-class CSRFConfigurationTestCase(CSRFTestCase):
-
-    @property
-    def urls(self):
-        urlpatterns = urls.urlpatterns
-        urlpatterns += patterns('', url(r'^test-form/', test_form))
-        return type('urls', (), dict(urlpatterns=urlpatterns))
-
-    def setUp(self):
-        super(CSRFConfigurationTestCase, self).setUp()
-        self.form_path = reverse(test_form)
-
-    def test_csrf_token_present_in_form(self):
-        if django.VERSION[:2] == (1, 1):
-            # This feature is not supported on django 1.1
-            return
-        response = self.client.get(self.form_path)
-        self.assertContains(response, "csrfmiddlewaretoken")
-
-    def test_cross_site_form_submission_fails(self):
-        if django.VERSION[:2] == (1, 1):
-            # This feature is not supported on django 1.1
-            return
-        response = self.client.post(self.form_path, {'text': 'text'})
-        self.assertEquals(response.status_code, 403)
-
-    def test_csrf_not_protecting_xml_rpc_views(self):
-        """call version and check that we didn't get 403"""
-        endpoint_path = reverse('dashboard_app.views.dashboard_xml_rpc_handler')
-        request_body = xmlrpclib.dumps((), methodname="version")
-        response = self.client.post(endpoint_path, request_body, "text/xml")
-        self.assertContains(response, "<methodResponse>", status_code=200)
-
-
-def test_form(request):
-    t = Template(template)
-    html = t.render(RequestContext(request, {'form': SingleTextFieldForm()}))
-    return HttpResponse(html)
-
-
-class SingleTextFieldForm(forms.Form):
-    text = forms.CharField()
-
-
-template = """
-    <html>
-     <body>
-      <form action="." method="POST">
-      {% csrf_token %} 
-       <table>{{ form.as_table }}</table>
-      </form>
-     </body>
-    </html>
-    """

=== removed file 'dashboard_app/tests/other/dashboard_api.py'
--- dashboard_app/tests/other/dashboard_api.py	2011-07-07 11:38:01 +0000
+++ dashboard_app/tests/other/dashboard_api.py	1970-01-01 00:00:00 +0000
@@ -1,458 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Unit tests for Dashboard API (XML-RPC interface)
-"""
-import contextlib
-import xmlrpclib
-
-from django.core.urlresolvers import reverse
-from django_testscenarios.ubertest import TransactionTestCase
-
-from dashboard_app.models import Bundle, BundleStream
-from dashboard_app.tests import fixtures
-from dashboard_app.tests.utils import DashboardXMLRPCViewsTestCase
-from dashboard_app.xmlrpc import errors
-
-
-class DashboardAPIStreamsTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('empty', {
-            'pathnames': [],
-            'expected_response': [],
-        }),
-        ('anonymous_stream', {
-            'pathnames': [
-                '/anonymous/',
-            ],
-            'expected_response': [{
-                'bundle_count': 0,
-                'user': 'anonymous-stream-owner',
-                'group': '',
-                'name': '',
-                'pathname': '/anonymous/'}],
-        }),
-        ('public_streams_are_shown', {
-            'pathnames': [
-                '/public/personal/user/',
-                '/public/team/group/',
-            ],
-            'expected_response': [{
-                'bundle_count': 0,
-                'user': 'user',
-                'group': '',
-                'name': '',
-                'pathname': '/public/personal/user/',
-            }, {
-                'bundle_count': 0,
-                'user': '',
-                'group': 'group',
-                'name': '',
-                'pathname': '/public/team/group/',
-            }],
-        }),
-        ('private_streams_are_not_shown', {
-            'pathnames': [
-                '/private/personal/user/',
-                '/private/team/group/',
-            ],
-            'expected_response': [],
-        }),
-    ]
-
-    def test_streams(self):
-        """
-        Check that calling streams() returns all the registered
-        streams visible to anonymous user.
-        """
-        with fixtures.created_bundle_streams(self.pathnames):
-            response = self.xml_rpc_call('streams')
-            self.assertEqual(response, self.expected_response)
-
-
-class DashboardAPIBundlesTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('empty', {
-            'query': '/anonymous/',
-            # make one anonymous stream so that we don't get 404 accessing missing one
-            'bundle_streams': ['/anonymous/'],
-            'bundles': [],
-            'expected_results': [],
-        }),
-        ('several_bundles_we_can_see', {
-            'query': '/anonymous/',
-            'bundle_streams': [],
-            'bundles': [
-                ('/anonymous/', 'test1.json', '{"foobar": 5}'),
-                ('/anonymous/', 'test2.json', '{"froz": "bot"}'),
-            ],
-            'expected_results': [{
-                'content_filename': 'test1.json',
-                'content_sha1': '72996acd68de60c766b60c2ca6f6169f67cdde19',
-            }, {
-                'content_filename': 'test2.json',
-                'content_sha1': '67dd49730d4e3b38b840f3d544d45cad74bcfb09',
-            }],
-        }),
-        ('several_bundles_in_other_stream', {
-            'query': '/anonymous/other/',
-            'bundle_streams': [],
-            'bundles': [
-                ('/anonymous/', 'test3.json', '{}'),
-                ('/anonymous/other/', 'test4.json', '{"x": true}'),
-            ],
-            'expected_results': [{
-                'content_filename': 'test4.json',
-                'content_sha1': 'bac148f29c35811441a7b4746a022b04c65bffc0',
-            }],
-        }),
-    ]
-
-    def test_bundles(self):
-        """
-        Make a bunch of bundles (all in a public branch) and check that
-        they are returned by the XML-RPC request.
-        """
-        with contextlib.nested(
-            fixtures.created_bundle_streams(self.bundle_streams),
-            fixtures.created_bundles(self.bundles)
-        ):
-            results = self.xml_rpc_call('bundles', self.query)
-            self.assertEqual(len(results), len(self.expected_results))
-            with fixtures.test_loop(zip(results, self.expected_results)) as loop_items:
-                for result, expected_result in loop_items:
-                    self.assertEqual(
-                            result['content_filename'],
-                            expected_result['content_filename'])
-                    self.assertEqual(
-                            result['content_sha1'],
-                            expected_result['content_sha1'])
-
-
-class DashboardAPIBundlesFailureTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('no_such_stream', {
-            'bundle_streams': [],
-            'query': '/anonymous/',
-        }),
-        ('no_anonymous_access_to_private_personal_streams', {
-            'bundle_streams': [
-                '/private/personal/user/',
-            ],
-            'query': '/private/personal/user/',
-        }),
-        ('no_anonymous_access_to_private_team_streams', {
-            'bundle_streams': [
-                '/private/team/group/',
-            ],
-            'query': '/private/team/group/',
-        }),
-    ]
-
-    def test_bundles_failure(self):
-        with fixtures.created_bundle_streams(self.bundle_streams):
-            try:
-                self.xml_rpc_call("bundles", self.query)
-            except xmlrpclib.Fault as ex:
-                self.assertEqual(ex.faultCode, errors.NOT_FOUND)
-            else:
-                self.fail("Should have raised an exception")
-
-
-class DashboardAPIGetTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('bundle_we_can_access', {
-            'content_sha1': '72996acd68de60c766b60c2ca6f6169f67cdde19',
-            'bundles': [
-                ('/anonymous/', 'test1.json', '{"foobar": 5}'),
-                ('/anonymous/', 'test2.json', '{"froz": "bot"}'),
-            ],
-            'expected_result': {
-                'content_filename': 'test1.json',
-                'content': '{"foobar": 5}',
-            }
-        }),
-    ]
-
-    def test_get(self):
-        """
-        Make a bunch of bundles (all in a public branch) and check that
-        we can get them back by calling get()
-        """
-        with fixtures.created_bundles(self.bundles):
-            result = self.xml_rpc_call('get', self.content_sha1)
-            self.assertTrue(isinstance(result, dict))
-            self.assertEqual(
-                    result['content_filename'],
-                    self.expected_result['content_filename'])
-            self.assertEqual(
-                    result['content'],
-                    self.expected_result['content'])
-
-
-class DashboardAPIGetFailureTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('bad_sha1', {
-            'content_sha1': '',
-        }),
-        ('no_access_to_personal_bundles', {
-            'bundles': [
-                ('/private/personal/bob/', 'test1.json', '{"foobar": 5}'),
-            ],
-        }),
-        ('no_access_to_named_personal_bundles', {
-            'bundles': [
-                ('/private/personal/bob/some-name/', 'test1.json', '{"foobar": 5}'),
-            ],
-        }),
-        ('no_access_to_team_bundles', {
-            'bundles': [
-                ('/private/team/members/', 'test1.json', '{"foobar": 5}'),
-            ],
-        }),
-        ('no_access_to_named_team_bundles', {
-            'bundles': [
-                ('/private/team/members/some-name/', 'test1.json', '{"foobar": 5}'),
-            ],
-        }),
-    ]
-
-    bundles = []
-    # SHA1 of the content used in scenarios above
-    content_sha1='72996acd68de60c766b60c2ca6f6169f67cdde19'
-
-    def test_get_failure(self):
-        with fixtures.created_bundles(self.bundles):
-            try:
-                self.xml_rpc_call('get', self.content_sha1)
-            except xmlrpclib.Fault as ex:
-                self.assertEqual(ex.faultCode, errors.NOT_FOUND)
-            else:
-                self.fail("Should have raised an exception")
-
-
-class DashboardAPIPutTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('store_to_public_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/anonymous/',
-        }),
-        ('store_to_public_named_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/anonymous/some-name/',
-        }),
-    ]
-
-    def setUp(self):
-        super(DashboardAPIPutTests, self).setUp()
-        self.bundle_stream = fixtures.create_bundle_stream(self.pathname)
-        self.bundle = None
-
-    def tearDown(self):
-        if self.bundle:
-            self.bundle.delete_files()
-        super(DashboardAPIPutTests, self).tearDown()
-
-    def test_put(self):
-        content_sha1 = self.xml_rpc_call(
-            "put", self.content, self.content_filename, self.pathname)
-        self.bundle = Bundle.objects.get(content_sha1=content_sha1)
-        self.assertEqual(self.bundle.content_sha1, content_sha1)
-        self.assertEqual(self.bundle.content.read(), self.content)
-        self.assertEqual(self.bundle.content_filename, self.content_filename)
-        self.assertEqual(self.bundle.bundle_stream.pathname, self.pathname)
-
-
-class DashboardAPIPutFailureTests(DashboardXMLRPCViewsTestCase):
-   
-    scenarios = [
-        ('store_to_personal_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/private/personal/user/',
-            'faultCode': errors.NOT_FOUND,
-            }),
-        ('store_to_named_personal_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/private/personal/user/name/',
-            'faultCode': errors.NOT_FOUND,
-            }),
-        ('store_to_team_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/private/team/group/',
-            'faultCode': errors.NOT_FOUND,
-            }),
-        ('store_to_named_team_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/private/team/group/name/',
-            'faultCode': errors.NOT_FOUND,
-            }),
-        ('store_to_missing_stream', {
-            'content': '{"foobar": 5}',
-            'content_filename': 'test1.json',
-            'pathname': '/anonymous/',
-            'faultCode': errors.NOT_FOUND,
-            'do_not_create': True,
-            }),
-        ]
-
-    def test_put_failure(self):
-        with contextlib.nested(
-            fixtures.created_bundle_streams(
-                [] if getattr(self, 'do_not_create', False) else [self.pathname]),
-            fixtures.created_bundles(getattr(self, 'bundles', []))
-        ):
-            try:
-                self.xml_rpc_call(
-                    "put", self.content, self.content_filename, self.pathname)
-            except xmlrpclib.Fault as ex:
-                self.assertEqual(ex.faultCode, self.faultCode)
-            else:
-                self.fail("Should have raised an exception")
-
-
-class DashboardAPIPutFailureTransactionTests(TransactionTestCase):
-
-    def setUp(self):
-        super(DashboardAPIPutFailureTransactionTests, self).setUp()
-        self.endpoint_path = reverse(
-            "dashboard_app.views.dashboard_xml_rpc_handler")
-        self.content_sha1 = None
-
-    def tearDown(self):
-        if self.content_sha1:
-            Bundle.objects.get(content_sha1=self.content_sha1).delete_files()
-        super(DashboardAPIPutFailureTransactionTests, self).tearDown()
-
-    def xml_rpc_call(self, method, *args):
-        request_body = xmlrpclib.dumps(tuple(args), methodname=method)
-        response = self.client.post(self.endpoint_path,
-                request_body, "text/xml")
-        return xmlrpclib.loads(response.content)[0][0]
-
-    def test_deserialize_failure_does_not_kill_the_bundle(self):
-        _pathname = '/anonymous/'
-        _content = '"unterminated string'
-        _content_filename = 'bad.json'
-        # The test goes via the xml-rpc interface to use views calling the
-        # put() API directly will never trigger transactions handling
-        with fixtures.created_bundle_streams([_pathname]):
-            self.content_sha1 = self.xml_rpc_call(
-                "put", _content, _content_filename, _pathname)
-            self.assertEqual(Bundle.objects.all().count(), 1)
-
-    def test_put_duplicate(self):
-        _bundles = [('/anonymous/', 'test1.json', '{"foobar": 5}')]
-        _content = '{"foobar": 5}'
-        _content_filename = 'test1.json'
-        _pathname = '/anonymous/'
-        with fixtures.created_bundles(_bundles):
-            try:
-                self.content_sha1 = self.xml_rpc_call(
-                    "put", _content, _content_filename, _pathname)
-            except xmlrpclib.Fault as ex:
-                self.assertEqual(ex.faultCode, errors.CONFLICT)
-            else:
-                self.fail("Should have raised an exception")
-
-
-class DashboardAPIMakeStreamTests(DashboardXMLRPCViewsTestCase):
-
-    scenarios = [
-        ('toplevel_anonymous/', {
-            'pathname': '/anonymous/',
-            'name': '',
-        }),
-        ('anonymous_with_slug', {
-            'pathname': '/anonymous/some-name/',
-            'name': '',
-        }),
-        ('anonymous_with_slug_and_name', {
-            'pathname': '/anonymous/some-name/',
-            'name': 'nonempty',
-        }),
-    ]
-
-    def setUp(self):
-        super(DashboardAPIMakeStreamTests, self).setUp()
-        self.response = self.xml_rpc_call("make_stream", self.pathname, self.name)
-
-    def test_response_is_pathname(self):
-        self.assertEqual(self.response, self.pathname)
-
-    def test_pathname_is_created(self):
-        self.assertEqual(BundleStream.objects.filter(pathname=self.pathname).count(), 1)
-
-    def test_pathname_has_name(self):
-        bundle_stream = BundleStream.objects.get(pathname=self.pathname)
-        self.assertEqual(self.name, bundle_stream.name)
-
-
-class DashboardAPIMakeStreamFailureTests(DashboardXMLRPCViewsTestCase):
-
-    _NAME = ""
-
-    scenarios = [
-        ('public_personal', {
-            'pathname': '/public/personal/NAME/',
-        }),
-        ('private_personal', {
-            'pathname': '/private/personal/NAME/',
-        }),
-        ('public_team', {
-            'pathname': '/public/team/NAME/',
-        }),
-        ('private_team', {
-            'pathname': '/private/team/NAME/',
-        }),
-        ('public_personal_with_slug', {
-            'pathname': '/public/personal/NAME/SLUG/',
-        }),
-        ('private_personal_with_slug', {
-            'pathname': '/private/personal/NAME/SLUG/',
-        }),
-        ('public_team_with_slug', {
-            'pathname': '/public/team/NAME/SLUG/',
-        }),
-        ('private_team_with_slug', {
-            'pathname': '/private/team/NAME/SLUG/',
-        }),
-        ('bogus', {
-            'pathname': '/bogus/pathname/'
-        }),
-    ]
-
-    def test_nonanonymous_streams(self):
-        try:
-            self.xml_rpc_call("make_stream", self.pathname, self._NAME)
-        except xmlrpclib.Fault as ex:
-            self.assertEqual(ex.faultCode, errors.FORBIDDEN)
-        else:
-            self.fail("Should have raised an exception")

=== removed file 'dashboard_app/tests/other/dataview.py'
--- dashboard_app/tests/other/dataview.py	2011-07-22 00:29:54 +0000
+++ dashboard_app/tests/other/dataview.py	1970-01-01 00:00:00 +0000
@@ -1,105 +0,0 @@
-# Copyright (C) 2011 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-from mocker import Mocker, expect
-from testtools import TestCase
-
-from dashboard_app.models import DataView
-
-
-class DataViewHandlerTests(TestCase):
-
-    text = """
-    <data-view name="foo">
-        <documentation>
-        Simple dataview that selects all bundle streams
-        </documentation>
-        <summary>List all bundle streams</summary>
-        <sql backend="sqlite">
-            SELECT *
-            FROM dashboard_app_bundlestreams
-            ORDER BY <value name="order_by"/>
-        </sql>
-        <arguments>
-            <argument name="order_by" default="pathname" type="string" help="sorting order"/>
-        </arguments>
-    </data-view>
-    """
-
-    def setUp(self):
-        super(DataViewHandlerTests, self).setUp()
-        self.dataview = DataView.repository.load_from_xml_string(self.text) 
-
-    def test_name_parsed_ok(self):
-        self.assertEqual(self.dataview.name, "foo")
-
-    def test_documentation_parsed_ok(self):
-        self.assertEqual(
-            self.dataview.documentation,
-            "Simple dataview that selects all bundle streams")
-
-    def test_summary_parsed_ok(self):
-        self.assertEqual(self.dataview.summary, "List all bundle streams")
-
-    def test_sql_parsed_ok(self):
-        self.assertTrue("sqlite" in self.dataview.backend_queries)
-        backend_query = self.dataview.backend_queries["sqlite"]
-        self.assertEqual(backend_query.backend, "sqlite")
-        self.assertEqual(
-            backend_query.sql_template,
-            "SELECT * FROM dashboard_app_bundlestreams ORDER BY {order_by}")
-        self.assertEqual(backend_query.argument_list, ["order_by"])
-
-    def test_arguments_parsed_ok(self):
-        self.assertEqual(len(self.dataview.arguments), 1)
-        arg = self.dataview.arguments[0]
-        self.assertEqual(arg.name, "order_by")
-        self.assertEqual(arg.default, "pathname")
-        self.assertEqual(arg.type, "string")
-        self.assertEqual(arg.help, "sorting order")
-
-
-class DataViewConnectionTests(TestCase):
-
-    def test_get_connection_without_sandbox(self):
-        # Mock connections['dataview'] to raise ConnectionDoesNotExist
-        from django.db.utils import ConnectionDoesNotExist
-        mocker = Mocker()
-        connections = mocker.replace("django.db.connections")
-        expect(connections['dataview']).throw(ConnectionDoesNotExist)
-        connection = mocker.replace("django.db.connection")
-        logging = mocker.replace("logging")
-        logging.warning("dataview-specific database connection not available, dataview query is NOT sandboxed")
-        with mocker:
-            observed = DataView.get_connection()
-            expected = connection
-            self.assertIs(observed, expected)
-
-    def test_get_connection_with_sandbox(self):
-        """
-        Test for DataView.get_connection()
-        """
-        # Mock connections['dataview'] to return special connection 
-        mocker = Mocker()
-        connections = mocker.replace("django.db.connections")
-        special_connection = mocker.mock()
-        expect(connections['dataview']).result(special_connection)
-        with mocker:
-            observed = DataView.get_connection()
-            expected = special_connection
-            self.assertIs(observed, expected)

=== removed file 'dashboard_app/tests/other/deserialization.py'
--- dashboard_app/tests/other/deserialization.py	2012-08-28 02:21:41 +0000
+++ dashboard_app/tests/other/deserialization.py	1970-01-01 00:00:00 +0000
@@ -1,750 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Unit tests of the Dashboard application
-"""
-import datetime
-import decimal
-
-from django_testscenarios.ubertest import (
-    TestCase,
-    TestCaseWithScenarios,
-    TransactionTestCase,
-)
-from django.contrib.auth.models import User
-from linaro_dashboard_bundle.errors import DocumentFormatError
-from json_schema_validator.errors import ValidationError
-from json_schema_validator.extensions import datetime_extension
-
-
-from dashboard_app.tests import fixtures
-from dashboard_app.models import (
-        Attachment,
-        Bundle,
-        BundleDeserializationError,
-        BundleStream,
-        HardwareDevice,
-        NamedAttribute,
-        SoftwarePackage,
-        SoftwareSource,
-        Test,
-        TestCase as TestCaseModel,
-        TestResult,
-        TestRun,
-        )
-from dashboard_app.helpers import (
-    BundleDeserializer,
-    IBundleFormatImporter,
-    BundleFormatImporter_1_0,
-    BundleFormatImporter_1_1,
-)
-
-
-
-class IBundleFormatImporterTests(TestCase):
-
-    def test_import_document_is_not_implemented(self):
-        importer = IBundleFormatImporter()
-        self.assertRaises(NotImplementedError,
-                          importer.import_document, None, None)
-
-
-class TestHelper(object):
-
-    def getUniqueString(self, prefix=None, max_length=None):
-        value = super(TestHelper, self).getUniqueString(prefix)
-        if max_length is not None:
-            if len(value) >= max_length:
-                value = super(TestHelper, self).getUniqueString("short")
-                if len(value) >= max_length:
-                    raise ValueError("Unable to satisfy request for random string with max_length=%d" % max_length)
-        return value
-
-    def getUniqueStringForField(self, model, field_name):
-        return self.getUniqueString(max_length=model._meta.get_field_by_name(field_name)[0].max_length)
-
-
-class BundleFormatImporter_1_1Tests(TestHelper, TestCaseWithScenarios):
-
-    scenarios = [
-        ('with_commit_timestamp', {
-            "commit_timestamp": datetime.datetime.now(),
-        }),
-        ('without_commit_timestamp', {
-            "commit_timestamp": None
-        })
-    ]
-
-    def c_getUniqueSoftwareSource(self):
-        source = {
-            "project_name": self.getUniqueStringForField(SoftwareSource, "project_name"),
-            "branch_url": self.getUniqueStringForField(SoftwareSource, "branch_url"),
-            "branch_vcs": self.getUniqueStringForField(SoftwareSource, "branch_vcs"),
-            "branch_revision": self.getUniqueStringForField(SoftwareSource, "branch_revision"),
-        }
-        if self.commit_timestamp is not None:
-            source["commit_timestamp"] = datetime_extension.to_json(self.commit_timestamp)
-        return source
-
-    def s_getUniqueTest(self):
-        return Test.objects.create(
-            test_id = self.getUniqueStringForField(Test, "test_id")
-        )
-
-    def s_getUniqueBundle(self):
-        return Bundle.objects.create(
-            bundle_stream = self.s_getUniqueBundleStream()
-        )
-
-    def s_getUniqueBundleStream(self):
-        return BundleStream.objects.create(
-            user = User.objects.create(username="legacy"),
-            group = None
-        )
-
-    def s_getUniqueTestRun(self):
-        return TestRun.objects.create(
-            test = self.s_getUniqueTest(),
-            bundle = self.s_getUniqueBundle(),
-            analyzer_assigned_date = datetime.datetime.now(),
-            analyzer_assigned_uuid = self.getUniqueStringForField(TestRun, "analyzer_assigned_uuid"),
-        )
-
-    def test_import_sources(self):
-        c_test_run = {
-            "software_context": {
-                "sources": [
-                    self.c_getUniqueSoftwareSource()
-                    for i in range(3)
-                ]
-            }
-        }
-        s_test_run = self.s_getUniqueTestRun()
-        importer = BundleFormatImporter_1_1()
-        importer._import_sources(c_test_run, s_test_run)
-        for c_source in c_test_run['software_context']['sources']:
-            filter = dict(
-                project_name = c_source['project_name'],
-                branch_url = c_source['branch_url'],
-                branch_vcs = c_source['branch_vcs'],
-                branch_revision = str(c_source['branch_revision']),
-                commit_timestamp = (
-                    datetime_extension.from_json(
-                        c_source["commit_timestamp"])
-                    if "commit_timestamp" in c_source
-                    else None)
-            )
-            s_source = SoftwareSource.objects.get(**filter)
-            self.assertTrue(s_source is not None)
-            self.assertTrue(s_source.pk is not None)
-            self.assertTrue(s_source in s_test_run.sources.all())
-
-
-class BundleBuilderMixin(object):
-    """
-    Helper mix-in for constructing bundle contents for unit testing
-    """
-
-    def getUniqueSoftwarePackage(self):
-        return {
-            "name": self.getUniqueStringForField(SoftwarePackage, "name"),
-            "version": self.getUniqueStringForField(SoftwarePackage, "version")
-        }
-
-    def getUniqueSoftwareImage(self):
-        return {
-            "desc": self.getUniqueStringForField(TestRun, "sw_image_desc")
-        }
-
-    def getUniqueSoftwareContext(self, num_packages=None):
-        if num_packages is None:
-            num_packages = 5 # Arbitrary choice
-        return {
-            "sw_image": self.getUniqueSoftwareImage,
-            "packages": [
-                self.getUniqueSoftwarePackage() for i in range(num_packages)]
-        }
-
-    def getUniqueAttributes(self):
-        attrs = {}
-        for i in range(3):
-            attrs[self.getUniqueStringForField(NamedAttribute, "name")] = \
-                    self.getUniqueStringForField(NamedAttribute, "value")
-        for i in range(3):
-            attrs[self.getUniqueStringForField(NamedAttribute, "name")] = self.getUniqueInteger()
-        return attrs
-
-    def getUniqueHardwareDevice(self):
-        return {
-            "device_type": self.getUniqueStringForField(HardwareDevice, "device_type"),
-            "description": self.getUniqueStringForField(HardwareDevice, "description"),
-            "attributes": self.getUniqueAttributes(),
-        }
-
-    def getUniqueHardwareContext(self, num_devices=None):
-        if num_devices is None:
-            num_devices = 5 # Another arbitrary choice
-        return {
-            "devices": [
-                self.getUniqueHardwareDevice() for i in range(num_devices)]
-        }
-
-
-class BundleFormatImporter_1_0Tests(
-    TestHelper,
-    TestCase,
-    BundleBuilderMixin):
-
-    def setUp(self):
-        super(BundleFormatImporter_1_0Tests, self).setUp()
-        self.importer = BundleFormatImporter_1_0()
-
-    def test_get_sw_context_with_context(self):
-        sw_context = self.getUniqueSoftwareContext()
-        test_run = {"sw_context": sw_context}
-        retval = self.importer._get_sw_context(test_run)
-        self.assertEqual(retval, sw_context)
-
-    def test_get_sw_context_without_context(self):
-        test_run = {} # empty test run
-        retval = self.importer._get_sw_context(test_run)
-        self.assertEqual(retval, {})
-
-    def test_get_hw_context_with_context(self):
-        hw_context = self.getUniqueHardwareContext()
-        test_run = {"hw_context": hw_context}
-        retval = self.importer._get_hw_context(test_run)
-        self.assertEqual(retval, hw_context)
-
-    def test_get_hw_context_without_context(self):
-        test_run = {} # empty test run
-        retval = self.importer._get_hw_context(test_run)
-        self.assertEqual(retval, {})
-
-    def test_translate_result_string(self):
-        self.assertEqual(
-            self.importer._translate_result_string("pass"),
-            TestResult.RESULT_PASS)
-        self.assertEqual(
-            self.importer._translate_result_string("fail"),
-            TestResult.RESULT_FAIL)
-        self.assertEqual(
-            self.importer._translate_result_string("skip"),
-            TestResult.RESULT_SKIP)
-        self.assertEqual(
-            self.importer._translate_result_string("unknown"),
-            TestResult.RESULT_UNKNOWN)
-
-    def test_translate_bogus_result_string(self):
-        self.assertRaises(KeyError,
-                          self.importer._translate_result_string,
-                          "impossible result")
-
-
-class BundleDeserializerSuccessTests(TestCaseWithScenarios):
-
-    json_text = '''
-    {
-        "format": "Dashboard Bundle Format 1.0",
-        "test_runs": [
-            {
-                "test_id": "some_test_id",
-                "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                "analyzer_assigned_date": "2010-12-31T23:59:59Z",
-                "time_check_performed": true,
-                "test_results": [
-                {
-                    "test_case_id": "some_test_case_id",
-                    "result": "unknown",
-                    "measurement": 1000.3,
-                    "units": "bogomips",
-                    "timestamp": "2010-09-17T16:34:21Z",
-                    "duration": "1d 1s 1us",
-                    "message": "text message",
-                    "log_filename": "file.txt",
-                    "log_lineno": 15,
-                    "attributes": {
-                        "attr1": "value1",
-                        "attr2": "value2"
-                    }
-                },
-                {
-                    "test_case_id": "some_test_case_id",
-                    "result": "unknown"
-                }
-                ],
-                "sw_context": {
-                    "packages": [
-                        {"name": "pkg1", "version": "1.0"},
-                        {"name": "pkg1", "version": "1.0"},
-                        {"name": "pkg2", "version": "0.5"}
-                    ],
-                    "sw_image": {
-                        "desc": "Ubuntu 10.10"
-                    }
-                },
-                "hw_context": {
-                    "devices": [{
-                        "device_type": "device.cpu",
-                        "description": "ARM SoC",
-                        "attributes": {
-                            "MHz": "600",
-                            "Revision": "3",
-                            "Implementer": "0x41"
-                        }}, {
-                        "device_type": "device.board",
-                        "description": "Beagle Board C4",
-                        "attributes": {
-                            "Revision": "C4"
-                        }
-                    }]
-                },
-                "attributes": {
-                    "testrun attr1": "value1",
-                    "testrun attr2": "value2"
-                },
-                "attachments": {
-                    "file.txt": [
-                        "line 1\\n",
-                        "line 2\\n"
-                    ]
-                }
-            }
-        ]
-    }
-    '''
-
-    scenarios = [
-        ('with_evolution', {
-            "prefer_evolution": True
-        }),
-        ('without_evolution', {
-            "prefer_evolution": False
-        })
-    ]
-
-    def _attrs2set(self, attrs):
-        """
-        Convert a collection of Attribute model instances into a python
-        frozenset of tuples (name, value).
-        """
-        return frozenset([(attr.name, attr.value) for attr in attrs.all()])
-
-    def _pkgs2set(self, pkgs):
-        """
-        Convert a collection of SoftwarePackage model instances into a python
-        frozenset of tuples (name, version).
-        """
-        return frozenset([(package.name, package.version) for package in pkgs])
-
-    def _devs2set(self, devs):
-        """
-        Convert a collection of HardareDevice model instances into a python
-        frozenset of tuples (device_type, description, attributes).
-        """
-        return frozenset([(
-            device.device_type,
-            device.description,
-            self._attrs2set(device.attributes)
-        ) for device in devs])
-
-    def setUp(self):
-        super(BundleDeserializerSuccessTests, self).setUp()
-        self.s_bundle = fixtures.create_bundle(
-            '/anonymous/', self.json_text, 'bundle.json')
-        # Decompose the data here
-        self.s_bundle.deserialize(prefer_evolution=self.prefer_evolution)
-        if not self.s_bundle.is_deserialized:
-            raise AssertionError("Deserialzation failed:" + self.s_bundle.deserialization_error.get().traceback)
-        # Here we trick a little, since there is just one of each of
-        # those models we can select them like this, the tests below
-        # validate that we did not pick up some random object by
-        # matching all the properties.
-        self.s_test = Test.objects.all()[0]
-        self.s_test_case = TestCaseModel.objects.all()[0]
-        self.s_test_run = TestRun.objects.all()[0]
-        self.s_test_result = TestResult.objects.all()[0]
-        self.s_attachment = Attachment.objects.all()[0]
-
-    def tearDown(self):
-        self.s_bundle.delete_files()
-        super(BundleDeserializerSuccessTests, self).tearDown()
-
-    def test_Test__test_id(self):
-        self.assertEqual(self.s_test.test_id, "some_test_id")
-
-    def test_Test__name_is_empty(self):
-        # Bundles have no way to convey this meta-data
-        # Unless the test was named manually by operator
-        # and existed prior to import it will not have a name
-        self.assertEqual(self.s_test.name, "")
-
-    def test_TestCase__test_is_same_as__Test(self):
-        self.assertEqual(self.s_test_case.test, self.s_test)
-
-    def test_TestCase__test_case_id(self):
-        self.assertEqual(self.s_test_case.test_case_id, "some_test_case_id")
-
-    def test_TestCase__name_is_empty(self):
-        # Same as test_Test__name_is_empty above
-        self.assertEqual(self.s_test_case.name, "")
-
-    def test_TestCase__units(self):
-        self.assertEqual(self.s_test_case.units, "bogomips")
-
-    def test_TestRun__bundle(self):
-        self.assertEqual(self.s_test_run.bundle, self.s_bundle)
-
-    def test_TestRun__test(self):
-        self.assertEqual(self.s_test_run.test, self.s_test)
-
-    def test_TestRun__analyzer_assigned_uuid(self):
-        self.assertEqual(
-            self.s_test_run.analyzer_assigned_uuid,
-            "1ab86b36-c23d-11df-a81b-002163936223")
-
-    def test_TestRun__analyzer_assigned_date(self):
-        self.assertEqual(
-            self.s_test_run.analyzer_assigned_date,
-            datetime.datetime(2010, 12, 31, 23, 59, 59, 0, None))
-
-    def test_TestRun__time_check_performed(self):
-        self.assertEqual(self.s_test_run.time_check_performed, True)
-
-    def test_TestRun__sw_image_desc(self):
-        self.assertEqual(self.s_test_run.sw_image_desc, "Ubuntu 10.10")
-
-    def test_TestRun__packages(self):
-        self.assertEqual(
-            self._pkgs2set(self.s_test_run.packages.all()),
-            frozenset([
-                ("pkg1", "1.0"),
-                ("pkg2", "0.5")]))
-
-    def test_TestRun__devices(self):
-        self.assertEqual(
-            self._devs2set(self.s_test_run.devices.all()),
-            frozenset([
-                ("device.cpu", "ARM SoC", frozenset([
-                    ("MHz", "600"),
-                    ("Revision", "3"),
-                    ("Implementer", "0x41")])
-                ),
-                ("device.board", "Beagle Board C4", frozenset([
-                    ("Revision", "C4")])
-                )]))
-
-    def test_TestRun__attributes(self):
-        self.assertEqual(
-            self._attrs2set(self.s_test_run.attributes.all()),
-            frozenset([
-                ("testrun attr1", "value1"),
-                ("testrun attr2", "value2")]))
-
-    def test_TestRun__attachments(self):
-        self.assertEqual(
-            self.s_test_run.attachments.all()[0],
-            self.s_attachment)
-
-    def test_TestRun__attachment__content_filename(self):
-        self.assertEqual(
-            self.s_attachment.content_filename,
-            "file.txt")
-
-    def test_TestRun__attachment__content(self):
-        self.assertEqual(
-            self.s_attachment.content.read(),
-            "line 1\nline 2\n")
-
-    def test_TestResult__test_run(self):
-        self.assertEqual(self.s_test_result.test_run, self.s_test_run)
-
-    def test_TestResult__test_case(self):
-        self.assertEqual(self.s_test_result.test_case, self.s_test_case)
-
-    def test_TestResult__result(self):
-        self.assertEqual(self.s_test_result.result, TestResult.RESULT_UNKNOWN)
-
-    def test_TestResult__measurement(self):
-        self.assertEqual(
-            self.s_test_result.measurement,
-            decimal.Decimal("1000.3"))
-
-    def test_TestResult__units(self):
-        self.assertEqual(self.s_test_result.units, "bogomips")
-
-    def test_TestResult__filename(self):
-        self.assertEqual(self.s_test_result.filename, "file.txt")
-
-    def test_TestResult__lineno(self):
-        self.assertEqual(self.s_test_result.lineno, 15)
-
-    def test_TestResult__message(self):
-        self.assertEqual(self.s_test_result.message, "text message")
-
-    def test_TestResult__duration(self):
-        self.assertEqual(
-            self.s_test_result.duration,
-            datetime.timedelta(days=1, seconds=1, microseconds=1))
-
-    def test_TestResult__timestamp(self):
-        self.assertEqual(
-            self.s_test_result.timestamp,
-            datetime.datetime(2010, 9, 17, 16, 34, 21, 0, None))
-
-    def test_TestResult__attributes(self):
-        self.assertEqual(
-            self._attrs2set(self.s_test_result.attributes.all()),
-            frozenset([
-                ("attr1", "value1"),
-                ("attr2", "value2")]))
-
-
-class Bundle13DeserializerSuccessTests(TestCase):
-
-    json_text = '''
-    {
-        "format": "Dashboard Bundle Format 1.3",
-        "test_runs": [
-            {
-                "test_id": "some_test_id",
-                "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                "analyzer_assigned_date": "2010-12-31T23:59:59Z",
-                "time_check_performed": true,
-                "test_results": [ ],
-                "tags": [
-                    "tag-1",
-                    "tag-2"
-                ]
-            }
-        ]
-    }
-    '''
-    
-    def setUp(self):
-        super(Bundle13DeserializerSuccessTests, self).setUp()
-        self.s_bundle = fixtures.create_bundle(
-            '/anonymous/', self.json_text, 'bundle.json')
-        # Decompose the data here
-        self.s_bundle.deserialize(prefer_evolution=False)
-        if not self.s_bundle.is_deserialized:
-            raise AssertionError("Deserialzation failed:" + self.s_bundle.deserialization_error.get().traceback)
-        # Link to test run for easier testing
-        self.s_test = self.s_bundle.test_runs.get()
-
-    def tearDown(self):
-        self.s_bundle.delete_files()
-        super(Bundle13DeserializerSuccessTests, self).tearDown()
-
-    def test_deserialize_tags(self):
-        self.assertEqual(self.s_test.tags.count(), 2)
-        self.assertEqual([tag.name for tag in self.s_test.tags.order_by('name').all()],
-                         ["tag-1", "tag-2"])
-
-
-class BundleDeserializerFailureTestCase(TestCaseWithScenarios):
-
-    scenarios = [
-        ("empty_string", {
-            "json_text": '',
-            "cause": ValueError,
-        }),
-        ("malformed_json", {
-            "json_text": '{',
-            "cause": ValueError,
-        }),
-        ("invalid_format", {
-            "json_text": '{"format": "MS Excel with 50 sheets"}',
-            "cause": DocumentFormatError
-        }),
-        ("invalid_datetime_value", {
-            'json_text': """
-            {
-            "format": "Dashboard Bundle Format 1.0",
-            "test_runs": [{
-                    "test_id":  "some_test_id",
-                    "test_results": [],
-                    "time_check_performed": false,
-                    "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                    "analyzer_assigned_date": "9999-99-99T99:99:99Z"
-                }]
-            }
-            """,
-            "cause": ValidationError
-        }),
-        ("invalid_datetime_content", {
-            'json_text': """
-            {
-            "format": "Dashboard Bundle Format 1.0",
-            "test_runs": [{
-                    "test_id":  "some_test_id",
-                    "test_results": [],
-                    "time_check_performed": false,
-                    "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                    "analyzer_assigned_date": {"nobody expected": "a dictionary"}
-                }]
-            }
-            """,
-            "cause": ValidationError
-        }),
-        ("invalid_uuid_value", {
-            'json_text': """
-            {
-            "format": "Dashboard Bundle Format 1.0",
-            "test_runs": [{
-                    "test_id":  "some_test_id",
-                    "test_results": [],
-                    "time_check_performed": false,
-                    "analyzer_assigned_uuid": "string that is not an uuid",
-                    "analyzer_assigned_date": "2010-12-31T23:59:59Z"
-                }]
-            }
-            """,
-            "cause": ValueError
-        }),
-        ("invalid_uuid_content", {
-            'json_text': """
-            {
-            "format": "Dashboard Bundle Format 1.0",
-            "test_runs": [{
-                    "test_id":  "some_test_id",
-                    "test_results": [],
-                    "time_check_performed": false,
-                    "analyzer_assigned_uuid": 12345,
-                    "analyzer_assigned_date": "2010-12-31T23:59:59Z"
-                }]
-            }
-            """,
-            "cause": ValidationError
-        }),
-        ("invalid_timedelta_content", {
-            'json_text': """
-            {
-            "format": "Dashboard Bundle Format 1.0",
-            "test_runs": [{
-                    "test_id":  "some_test_id",
-                    "test_results": [],
-                    "time_check_performed": false,
-                    "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                    "analyzer_assigned_date": "2010-12-31T23:59:59Z",
-                    "test_results": [{
-                        "result": "pass",
-                        "duration": 19123123123123123132
-                    }]
-                }]
-            }
-            """,
-            "cause": ValidationError
-        }),
-    ]
-
-    def setUp(self):
-        super(BundleDeserializerFailureTestCase, self).setUp()
-        self.s_bundle = fixtures.create_bundle(
-            '/anonymous/', self.json_text, 'bundle.json')
-
-    def tearDown(self):
-        self.s_bundle.delete_files()
-        super(BundleDeserializerFailureTestCase, self).tearDown()
-
-    def test_deserializer_failure_without_evolution(self):
-        try:
-            BundleDeserializer().deserialize(self.s_bundle, prefer_evolution=False)
-        except Exception as ex:
-            self.assertIsInstance(ex, self.cause)
-        else:
-            self.fail("Should have raised an exception")
-
-    def test_deserializer_failure_with_evolution(self):
-        try:
-            BundleDeserializer().deserialize(self.s_bundle, prefer_evolution=True)
-        except Exception as ex:
-            self.assertIsInstance(ex, self.cause)
-        else:
-            self.fail("Should have raised an exception")
-
-
-class BundleDeserializerAtomicityTestCase(TransactionTestCase):
-    # Importing this bundle will fail as analyzer_assigned_uuid is not
-    # unique. Due to proper transaction handling the first test run
-    # model instance will not be visible after the failed upload
-    json_text = """
-    {
-        "format": "Dashboard Bundle Format 1.0",
-        "test_runs": [
-            {
-                "test_id": "some_test_id",
-                "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                "analyzer_assigned_date": "2010-12-31T23:59:59Z",
-                "time_check_performed": true,
-                "test_results": []
-            }, {
-                "test_id": "some_test_id",
-                "analyzer_assigned_uuid": "1ab86b36-c23d-11df-a81b-002163936223",
-                "analyzer_assigned_date": "2010-12-31T23:59:59Z",
-                "time_check_performed": true,
-                "test_results": []
-            }
-        ]
-    }
-    """
-
-    def setUp(self):
-        super(BundleDeserializerAtomicityTestCase, self).setUp()
-        self.s_bundle = fixtures.create_bundle(
-            '/anonymous/', self.json_text, 'bundle.json')
-
-    def tearDown(self):
-        self.s_bundle.delete_files()
-        super(BundleDeserializerAtomicityTestCase, self).tearDown()
-
-    def test_bundle_deserialization_failed(self):
-        self.s_bundle.deserialize()
-        self.assertFalse(self.s_bundle.is_deserialized)
-
-    def test_bundle_count(self):
-        self.s_bundle.deserialize()
-        self.assertEqual(Bundle.objects.count(), 1)
-
-    def test_bundle_deserialization_error_count(self):
-        self.s_bundle.deserialize()
-        self.assertEqual(BundleDeserializationError.objects.count(), 1)
-
-    def test_error_trace(self):
-        self.s_bundle.deserialize()
-        # The message depends on the database -- even the version of the
-        # database.  This is a little ugly but it's better than not knowing
-        # what really happened and hiding other potential bugs that would
-        # otherwise be masked here.
-        error_message = self.s_bundle.deserialization_error.error_message
-        error_first_line = error_message.splitlines()[0].strip()
-        self.assertIn(
-            error_first_line,
-            [
-                'A test with UUID 1ab86b36-c23d-11df-a81b-002163936223 already exists',
-                'column analyzer_assigned_uuid is not unique',
-                u'duplicate key value violates unique constraint '
-                '"dashboard_app_testrun_analyzer_assigned_uuid_key"',
-                ])
-
-    def test_deserialization_failure_does_not_leave_junk_behind(self):
-        self.s_bundle.deserialize()
-        self.assertRaises(
-            TestRun.DoesNotExist, TestRun.objects.get,
-            analyzer_assigned_uuid="1ab86b36-c23d-11df-a81b-002163936223")

=== removed file 'dashboard_app/tests/other/login.py'
--- dashboard_app/tests/other/login.py	2012-08-28 01:45:04 +0000
+++ dashboard_app/tests/other/login.py	1970-01-01 00:00:00 +0000
@@ -1,120 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Guilherme Salgado <guilherme.salgado@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Tests for the login bits of Launch Control.
-"""
-import cgi
-import httplib
-
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.test import TestCase
-
-from django_openid_auth.models import UserOpenID
-from django_openid_auth.tests.test_views import StubOpenIDProvider
-import django_openid_auth.tests.urls
-
-from openid.fetchers import setDefaultFetcher
-
-from dashboard_app.tests.utils import TestClient
-
-import lava_server.urls
-
-class TestOpenIDLogin(TestCase):
-
-    urls = tuple(
-        django_openid_auth.tests.urls.urlpatterns
-        + lava_server.urls.urlpatterns)
-    _username = 'someuser'
-    _identity_url = 'http://example.com/identity'
-
-    def test_positive_response_from_provider(self):
-        self.create_user()
-        openid_request = self.initiate_login()
-
-        # Simulate a positive assertion from the server.
-        openid_response = openid_request.answer(True)
-
-        # Use that response to complete the authentication.
-        response = self.complete(openid_response)
-
-        # And the user is now logged in.
-        response = self.client.get('/getuser/')
-        self.assertEquals(response.content, self._username)
-
-    def test_negative_response_from_provider(self):
-        openid_request = self.initiate_login()
-
-        # Simulate a negative assertion from the server.
-        openid_response = openid_request.answer(False)
-
-        # Use that response to complete the authentication.
-        response = self.complete(openid_response)
-
-        # Since we got a negative assertion from the server, no user is logged
-        # in.
-        response = self.client.get('/getuser/')
-        self.assertEquals(response.content, '')
-
-    def setUp(self):
-        super(TestOpenIDLogin, self).setUp()
-        # Use StubOpenIDProvider and _identity_url as our fixed SSO so that
-        # we always get a successful OpenID response for _identity_url.
-        self.provider = StubOpenIDProvider('http://example.com/')
-        setDefaultFetcher(self.provider, wrap_exceptions=False)
-        self.missing_sso_server_url = object()
-        self.orig_sso_server_url = getattr(
-            settings, 'OPENID_SSO_SERVER_URL', self.missing_sso_server_url)
-        settings.OPENID_SSO_SERVER_URL = self._identity_url
-        self.client = TestClient()
-
-    def tearDown(self):
-        super(TestOpenIDLogin, self).tearDown()
-        setDefaultFetcher(None)
-        if self.orig_sso_server_url == self.missing_sso_server_url:
-            del settings.OPENID_SSO_SERVER_URL
-        else:
-            settings.OPENID_SSO_SERVER_URL = self.orig_sso_server_url
-
-    def create_user(self):
-        user = User(username=self._username)
-        user.save()
-        # Associate our newly created user with the identity URL.
-        useropenid = UserOpenID(
-            user=user, claimed_id=self._identity_url,
-            display_id=self._identity_url)
-        useropenid.save()
-
-    def initiate_login(self):
-        response = self.client.get('/openid/login/')
-        self.assertEqual(httplib.OK, response.status_code)
-        openid_request = self.provider.parseFormPost(response.content)
-        self.assertTrue(openid_request.return_to.startswith(
-            'http://testserver/openid/complete/'))
-        return openid_request
-
-    def complete(self, openid_response):
-        """Complete an OpenID authentication request."""
-        webresponse = self.provider.server.encodeResponse(openid_response)
-        self.assertEquals(webresponse.code, 302)
-        redirect_to = webresponse.headers['location']
-        self.assertTrue(redirect_to.startswith(
-            'http://testserver/openid/complete/'))
-        return self.client.get('/openid/complete/',
-            dict(cgi.parse_qsl(redirect_to.split('?', 1)[1])))

=== removed file 'dashboard_app/tests/other/test_client.py'
--- dashboard_app/tests/other/test_client.py	2011-07-01 13:07:40 +0000
+++ dashboard_app/tests/other/test_client.py	1970-01-01 00:00:00 +0000
@@ -1,63 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Unit tests of the TestClient support class
-"""
-from django.contrib.auth.models import User
-from django.http import HttpResponse
-from django.test import TestCase
-
-from dashboard_app.tests.utils import TestClient
-
-
-def auth_test(request):
-    response = HttpResponse(mimetype="text/plain")
-    if (request.user and request.user.is_authenticated and
-        request.user.is_active):
-        response.write(request.user.username)
-    response['Content-length'] = str(len(response.content))
-    return response
-
-
-class local_urls:
-    from django.conf.urls.defaults import patterns, url
-    urlpatterns = patterns('', url(r'^auth-test/$', auth_test))
-
-
-class TestClientTest(TestCase):
-
-    _USER = "user"
-
-    urls = local_urls
-
-    def setUp(self):
-        super(TestClientTest, self).setUp()
-        self.client = TestClient()
-        self.user = User(username=self._USER)
-        self.user.save()
-
-    def test_auth(self):
-        self.client.login_user(self.user)
-        response = self.client.get("/auth-test/")
-        self.assertEqual(response.content, self._USER)
-
-    def test_no_auth(self):
-        response = self.client.get("/auth-test/")
-        self.assertEqual(response.content, '')
-

=== removed directory 'dashboard_app/tests/regressions'
=== removed file 'dashboard_app/tests/regressions/LP658917.json'
--- dashboard_app/tests/regressions/LP658917.json	2010-10-12 08:51:08 +0000
+++ dashboard_app/tests/regressions/LP658917.json	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "test_case_id": "conformance.behavior.timers.1-1", 
-          "result": "pass"
-        } 
-      ], 
-      "analyzer_assigned_date": "2010-10-12T07:52:36Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "ba3c5f80-d5d6-11df-ad98-002163936223", 
-      "test_id": "posixtestsuite"
-    }
-  ], 
-  "format": "Dashboard Bundle Format 1.0"
-}

=== removed file 'dashboard_app/tests/regressions/LP658917.py'
--- dashboard_app/tests/regressions/LP658917.py	2011-05-23 17:02:43 +0000
+++ dashboard_app/tests/regressions/LP658917.py	1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Regression test for LP:658917
-"""
-
-from django.db import IntegrityError
-
-from django_testscenarios.ubertest import TestCase
-
-from dashboard_app.models import Bundle
-from dashboard_app.xmlrpc import DashboardAPI
-from pkg_resources import resource_string
-
-from dashboard_app.tests import fixtures
-
-class LP658917(TestCase):
-
-
-    def setUp(self):
-        super(LP658917, self).setUp()
-        self.bundle_stream = fixtures.create_bundle_stream("/anonymous/")
-        self.dashboard_api = DashboardAPI()
-        self.content_sha1 = None
-
-    def tearDown(self):
-        if self.content_sha1:
-            Bundle.objects.get(content_sha1=self.content_sha1).delete_files()
-        super(LP658917, self).tearDown()
-
-    def test_658917(self):
-        """TestCase.units is not assigned a null value"""
-        try:
-            self.content_sha1 = self.dashboard_api.put(
-                resource_string(__name__, 'LP658917.json'),
-                'LP658917.json', self.bundle_stream.pathname)
-        except IntegrityError:
-            self.fail("LP658917 regression, IntegrityError raised")

=== removed file 'dashboard_app/tests/regressions/__init__.py'
=== removed file 'dashboard_app/tests/utils.py'
--- dashboard_app/tests/utils.py	2011-07-22 00:29:54 +0000
+++ dashboard_app/tests/utils.py	1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
-"""
-Django-specific test utilities
-"""
-import xmlrpclib
-
-from django.conf import settings
-from django.contrib.auth import login
-from django.core.urlresolvers import reverse
-from django.http import HttpRequest
-from django.test.client import Client
-from django.utils.importlib import import_module
-
-from django_testscenarios.ubertest import (TestCase, TestCaseWithScenarios)
-
-
-class CSRFTestCase(TestCase):
-    """
-    Subclass of django's own test.TestCase that allows to interact with cross
-    site request forgery protection that is disabled by the regular
-    TestCase.
-
-    TODO: Remove this
-    """
-
-    def setUp(self):
-        super(CSRFTestCase, self).setUp()
-        self.client = Client(enforce_csrf_checks=True)
-
-
-class TestClient(Client):
-
-    def login_user(self, user):
-        """
-        Login as specified user, does not depend on auth backend (hopefully)
-
-        This is based on Client.login() with a small hack that does not
-        require the call to authenticate()
-        """
-        if not 'django.contrib.sessions' in settings.INSTALLED_APPS:
-            raise EnvironmentError("Unable to login without django.contrib.sessions in INSTALLED_APPS")
-        user.backend = "%s.%s" % ("django.contrib.auth.backends",
-                                  "ModelBackend")
-        engine = import_module(settings.SESSION_ENGINE)
-
-        # Create a fake request to store login details.
-        request = HttpRequest()
-        if self.session:
-            request.session = self.session
-        else:
-            request.session = engine.SessionStore()
-        login(request, user)
-
-        # Set the cookie to represent the session.
-        session_cookie = settings.SESSION_COOKIE_NAME
-        self.cookies[session_cookie] = request.session.session_key
-        cookie_data = {
-            'max-age': None,
-            'path': '/',
-            'domain': settings.SESSION_COOKIE_DOMAIN,
-            'secure': settings.SESSION_COOKIE_SECURE or None,
-            'expires': None,
-        }
-        self.cookies[session_cookie].update(cookie_data)
-
-        # Save the session values.
-        request.session.save()
-
-
-class DashboardViewsTestCase(TestCaseWithScenarios):
-    """
-    TODO: Remove this
-    """
-
-
-class DashboardXMLRPCViewsTestCase(TestCaseWithScenarios):
-    """
-    Helper base class for doing XML-RPC requests
-    """
-
-    def setUp(self):
-        super(DashboardXMLRPCViewsTestCase, self).setUp()
-        self.endpoint_path = reverse(
-            "dashboard_app.views.dashboard_xml_rpc_handler")
-
-    def xml_rpc_call(self, method, *args):
-        request_body = xmlrpclib.dumps(tuple(args), methodname=method)
-        response = self.client.post(self.endpoint_path,
-                request_body, "text/xml")
-        return xmlrpclib.loads(response.content)[0][0]

=== removed directory 'dashboard_app/tests/views'
=== removed file 'dashboard_app/tests/views/__init__.py'
=== removed file 'dashboard_app/tests/views/bundle_stream_list_view.py'
--- dashboard_app/tests/views/bundle_stream_list_view.py	2012-08-28 00:43:11 +0000
+++ dashboard_app/tests/views/bundle_stream_list_view.py	1970-01-01 00:00:00 +0000
@@ -1,93 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Unit tests for dashboard_app.views.bundle_stream_list
-"""
-
-from django.contrib.auth.models import User
-from django.core.urlresolvers import reverse
-
-from dashboard_app.tests import fixtures
-from dashboard_app.tests.utils import (
-    DashboardViewsTestCase,
-    TestClient,
-)
-
-
-class BundleStreamListViewAnonymousTest(DashboardViewsTestCase):
-
-    scenarios = [
-        ('empty', {
-            'bundle_streams': [],
-        }),
-        ('public_streams', {
-            'bundle_streams': [
-                '/anonymous/',
-                '/anonymous/name/',
-                '/public/personal/user/',
-                '/public/personal/user/name/',
-                '/public/team/group/',
-                '/public/team/group/name/',
-            ]
-        }),
-        ('private_streams', {
-            'bundle_streams': [
-                '/private/personal/user/',
-                '/private/personal/user/name/',
-                '/private/team/group/',
-                '/private/team/group/name/',
-            ]
-        }),
-    ]
-
-    def setUp(self):
-        super(BundleStreamListViewAnonymousTest, self).setUp()
-        self.url = reverse("dashboard_app.views.bundle_stream_list")
-        self.user = None
-
-    def test_status_code(self):
-        response = self.client.get(self.url)
-        self.assertEqual(response.status_code, 200)
-
-    def test_template_used(self):
-        response = self.client.get(self.url)
-        self.assertTemplateUsed(response,
-                "dashboard_app/bundle_stream_list.html")
-
-    def test_listed_bundles_are_the_ones_we_should_see(self):
-        with fixtures.created_bundle_streams(self.bundle_streams) as bundle_streams:
-            response = self.client.get(self.url)
-            expected_bsl = sorted(
-                    [bundle_stream.pk for bundle_stream in
-                        bundle_streams if
-                        bundle_stream.is_accessible_by(self.user)])
-            effective_bsl = sorted(
-                    [bundle_stream.pk for bundle_stream in
-                        response.context['bundle_stream_table'].data.queryset])
-            self.assertEqual(effective_bsl, expected_bsl)
-
-
-class BundleStreamListViewAuthorizedTest(BundleStreamListViewAnonymousTest):
-
-    def setUp(self):
-        super(BundleStreamListViewAuthorizedTest, self).setUp()
-        self.client = TestClient()
-        self.user = User.objects.create(username='user')
-        self.user.groups.create(name='group')
-        self.client.login_user(self.user)

=== removed file 'dashboard_app/tests/views/redirects.py'
--- dashboard_app/tests/views/redirects.py	2011-08-24 04:36:41 +0000
+++ dashboard_app/tests/views/redirects.py	1970-01-01 00:00:00 +0000
@@ -1,130 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.core.urlresolvers import reverse
-from django_testscenarios.ubertest import TestCase
-
-from dashboard_app.tests import fixtures
-
-
-class RedirectTests(TestCase):
-
-    _PATHNAME = "/anonymous/"
-    _BUNDLE_TEXT = """
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "test_case_id": "test-case-0", 
-          "result": "pass"
-        } 
-      ], 
-      "analyzer_assigned_date": "2010-10-15T22:04:46Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000001",
-      "test_id": "examples"
-    }
-  ], 
-  "format": "Dashboard Bundle Format 1.0"
-}
-    """
-    _BUNDLE_NAME = "whatever.json"
-
-    def setUp(self):
-        super(RedirectTests, self).setUp()
-        self.bundle = fixtures.create_bundle(self._PATHNAME, self._BUNDLE_TEXT, self._BUNDLE_NAME)
-        self.bundle.deserialize()
-        self.assertTrue(self.bundle.is_deserialized)
-
-    def test_bundle_permalink(self):
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_bundle",
-                    args=(self.bundle.content_sha1, )))
-        self.assertRedirects(response, self.bundle.get_absolute_url())
-
-    def test_bundle_permalink_trailing(self):
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_bundle",
-                    args=(self.bundle.content_sha1, 'trailing/')))
-        self.assertRedirects(
-            response, self.bundle.get_absolute_url() + 'trailing/',
-            target_status_code=404)
-
-    def test_bundle_permalink_query_string(self):
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_bundle",
-                    args=(self.bundle.content_sha1, )), data={'foo': 'bar'})
-        self.assertRedirects(
-            response, self.bundle.get_absolute_url()+'?foo=bar')
-
-    def test_test_run_permalink(self):
-        test_run = self.bundle.test_runs.all()[0]
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_test_run",
-                    args=(test_run.analyzer_assigned_uuid, )))
-        self.assertRedirects(response, test_run.get_absolute_url())
-
-    def test_test_run_permalink_trailing(self):
-        test_run = self.bundle.test_runs.all()[0]
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_test_run",
-                    args=(test_run.analyzer_assigned_uuid, 'trailing/')))
-        self.assertRedirects(
-            response, test_run.get_absolute_url() + 'trailing/',
-            target_status_code=404)
-
-    def test_test_run_permalink_query_string(self):
-        test_run = self.bundle.test_runs.all()[0]
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_test_run",
-                    args=(test_run.analyzer_assigned_uuid, )),
-            data={'foo': 'bar'})
-        self.assertRedirects(
-            response, test_run.get_absolute_url() + '?foo=bar')
-
-    def test_test_result_permalink(self):
-        test_run = self.bundle.test_runs.all()[0]
-        test_result = test_run.test_results.all()[0]
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_test_result",
-                    args=(test_run.analyzer_assigned_uuid,
-                          test_result.relative_index)))
-        self.assertRedirects(response, test_result.get_absolute_url())
-
-    def test_test_result_permalink_trailing(self):
-        test_run = self.bundle.test_runs.all()[0]
-        test_result = test_run.test_results.all()[0]
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_test_result",
-                    args=(test_run.analyzer_assigned_uuid,
-                          test_result.relative_index, 'trailing/')))
-        self.assertRedirects(
-            response, test_result.get_absolute_url() + 'trailing/',
-            target_status_code=404)
-
-    def test_test_result_permalink_query_string(self):
-        test_run = self.bundle.test_runs.all()[0]
-        test_result = test_run.test_results.all()[0]
-        response = self.client.get(
-            reverse("dashboard_app.views.redirect_to_test_result",
-                    args=(test_run.analyzer_assigned_uuid,
-                          test_result.relative_index)),
-            data={'foo': 'bar'})
-        self.assertRedirects(
-            response, test_result.get_absolute_url() + '?foo=bar')

=== removed file 'dashboard_app/tests/views/test_run_detail_view.py'
--- dashboard_app/tests/views/test_run_detail_view.py	2011-07-22 00:29:54 +0000
+++ dashboard_app/tests/views/test_run_detail_view.py	1970-01-01 00:00:00 +0000
@@ -1,99 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Deepti B. Kalakeri<deepti.kalakeri@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from django_testscenarios.ubertest import (TestCase, TestCaseWithScenarios)
-from dashboard_app.models import BundleStream, TestRun
-from django.contrib.auth.models import (User, Group)
-
-from dashboard_app.tests.utils import TestClient
-
-
-class TestRunDetailView(TestCase):
-
-    fixtures = ["test_run_detail.json"] 
-
-    def setUp(self):
-        super(TestRunDetailView, self).setUp()
-        self.test_run_url = TestRun.objects.get(pk=1).get_absolute_url()
-
-    def testrun_valid_page_view(self):
-        response = self.client.get(self.test_run_url)
-        self.assertEqual(response.status_code, 200)
-
-    def test_template_used(self):
-        response = self.client.get(self.test_run_url)
-        self.assertTemplateUsed(response,
-                "dashboard_app/test_run_detail.html")
-
-    #def testrun_invalid_page_view(self):
-    #    invalid_uuid = "0000000-0000-0000-0000-000000000000" 
-    #    invalid_test_run_url = reverse("dashboard_app.views.test_run_detail",
-    #                                   args=[invalid_uuid])
-    #    response = self.client.get(invalid_test_run_url)
-    #    self.assertEqual(response.status_code, 404)
-
-
-class TestRunViewAuth(TestCaseWithScenarios):
-
-    _USER = "private_owner"
-    _GROUP = "private_group"
-    _UNRELATED_USER = "unrelated-user"
-    fixtures = ["test_run_detail.json"] 
-
-    scenarios = [
-        ("anonymous_accessing_private", {
-            "accessing_user": None,
-            "resource_owner": _USER
-        }),
-        ("anonymous_accessing_shared", {
-            "accessing_user": None, 
-            "resource_owner": _GROUP
-        }),
-        ("unrelated_accessing_private", {
-            "accessing_user": _UNRELATED_USER,
-            "resource_owner": _USER,
-        }),
-        ("unrelated_accessing_shared", {
-            "accessing_user": _UNRELATED_USER,
-            "resource_owner": _GROUP
-        }),
-    ]
-
-    def setUp(self):
-        super(TestRunViewAuth, self).setUp()
-        self.test_run_url = TestRun.objects.get(pk=1).get_absolute_url()
-
-        # Set resource ownership to group or user
-        bundle_stream = BundleStream.objects.get(pk=1)
-        if self.resource_owner == self._GROUP:
-            bundle_stream.group = Group.objects.create(name=self._USER)
-        elif self.resource_owner == self._USER:
-            bundle_stream.user = User.objects.create(username=self._USER)
-        bundle_stream.is_public = False
-        bundle_stream.is_anonymous = False
-        bundle_stream.save()
-
-        if self.accessing_user:
-            self.accessing_user = User.objects.get_or_create(username=self.accessing_user)[0]
-            self.client = TestClient()
-            self.client.login_user(self.accessing_user)
-       
-    def test_run_unauth_access(self):
-        response = self.client.get(self.test_run_url)
-        self.assertEqual(response.status_code, 404)

=== removed file 'dashboard_app/tests/views/test_run_list_view.py'
--- dashboard_app/tests/views/test_run_list_view.py	2011-05-30 16:32:55 +0000
+++ dashboard_app/tests/views/test_run_list_view.py	1970-01-01 00:00:00 +0000
@@ -1,97 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Unit tests for dashboard_app.views.test_run_list
-"""
-
-from django.contrib.auth.models import User, Group
-from django.core.urlresolvers import reverse
-from django_testscenarios.ubertest import TestCaseWithScenarios
-
-from dashboard_app.tests import fixtures
-from dashboard_app.tests.utils import TestClient
-
-
-class TestRunListViewAnonymousTest(TestCaseWithScenarios):
-
-    scenarios = [
-        ('anonymous_stream', {
-            'pathname': '/anonymous/',
-        }),
-        ('anonymous_named_stream', {
-            'pathname': '/anonymous/name/',
-        }),
-        ('public_personal_stream', {
-            'pathname': '/public/personal/user/',
-        }),
-        ('public_personal_named_stream', {
-            'pathname': '/public/personal/user/name/',
-        }),
-        ('public_team_stream', {
-            'pathname': '/public/team/group/',
-        }),
-        ('public_team_named_stream', {
-            'pathname': '/public/team/group/name/',
-        }),
-        ('private_personal_stream', {
-            'pathname': '/private/personal/user/',
-        }),
-        ('private_personal_named_stream', {
-            'pathname': '/private/personal/user/name/',
-        }),
-        ('private_team_stream', {
-            'pathname': '/private/team/group/',
-        }),
-        ('private_team_named_stream', {
-            'pathname': '/private/team/group/name/',
-        }),
-    ]
-
-    def setUp(self):
-        super(TestRunListViewAnonymousTest, self).setUp()
-        self.bundle_stream = fixtures.create_bundle_stream(self.pathname)
-        self.user = None
-        self.url = reverse("dashboard_app.views.test_run_list", args=[self.bundle_stream.pathname])
-
-    def test_status_code(self):
-        response = self.client.get(self.url)
-        if self.bundle_stream.is_accessible_by(self.user):
-            self.assertEqual(response.status_code, 200)
-        else:
-            self.assertEqual(response.status_code, 404)
-
-    def test_template_used(self):
-        response = self.client.get(self.url)
-        if self.bundle_stream.is_accessible_by(self.user):
-            self.assertTemplateUsed(response,
-                "dashboard_app/test_run_list.html")
-        else:
-            self.assertTemplateUsed(response,
-                "404.html")
-
-
-class TestRunListViewAuthorizedTest(TestRunListViewAnonymousTest):
-
-    def setUp(self):
-        super(TestRunListViewAuthorizedTest, self).setUp()
-        self.client = TestClient()
-        self.user = User.objects.get_or_create(username="user")[0]
-        self.group = Group.objects.get_or_create(name="group")[0]
-        self.user.groups.add(self.group)
-        self.client.login_user(self.user)

=== removed file 'dashboard_app/urls.py'
--- dashboard_app/urls.py	2013-09-13 14:16:05 +0000
+++ dashboard_app/urls.py	1970-01-01 00:00:00 +0000
@@ -1,90 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-URL mappings for the Dashboard application
-"""
-from django.conf.urls.defaults import *
-
-urlpatterns = patterns(
-    'dashboard_app.views',
-    url(r'^$', 'index'),
-    url(r'^ajax/bundle-viewer/(?P<pk>[0-9]+)/$', 'ajax_bundle_viewer'),
-    url(r'^data-views/$', 'data_view_list'),
-    url(r'^data-views/(?P<name>[a-zA-Z0-9-_]+)/$', 'data_view_detail'),
-    url(r'^reports/$', 'report_list'),
-    url(r'^reports/(?P<name>[a-zA-Z0-9-_]+)/$', 'report_detail'),
-    url(r'^filters/$', 'filters.views.filters_list'),
-    url(r'^filters/\+add$', 'filters.views.filter_add'),
-    url(r'^filters/\+add-preview-json$', 'filters.views.filter_preview_json'),
-    url(r'^filters/\+add-cases-for-test-json$', 'filters.views.filter_add_cases_for_test_json'),
-    url(r'^filters/\+get-tests-json$', 'filters.views.get_tests_json'),
-    url(r'^filters/\+get-test-cases-json$', 'filters.views.get_test_cases_json'),
-    url(r'^filters/\+attribute-name-completion-json$', 'filters.views.filter_attr_name_completion_json'),
-    url(r'^filters/\+attribute-value-completion-json$', 'filters.views.filter_attr_value_completion_json'),
-    url(r'^filters/~(?P<username>[^/]+)/(?P<name>[a-zA-Z0-9-_]+)$', 'filters.views.filter_detail'),
-    url(r'^filters/~(?P<username>[^/]+)/(?P<name>[a-zA-Z0-9-_]+)/json$', 'filters.views.filter_json'),
-    url(r'^filters/~(?P<username>[^/]+)/(?P<name>[a-zA-Z0-9-_]+)/\+edit$', 'filters.views.filter_edit'),
-    url(r'^filters/~(?P<username>[^/]+)/(?P<name>[a-zA-Z0-9-_]+)/\+subscribe$', 'filters.views.filter_subscribe'),
-    url(r'^filters/~(?P<username>[^/]+)/(?P<name>[a-zA-Z0-9-_]+)/\+delete$', 'filters.views.filter_delete'),
-    url(r'^filters/~(?P<username>[^/]+)/(?P<name>[a-zA-Z0-9-_]+)/\+compare/(?P<tag1>[a-zA-Z0-9-_: .]+)/(?P<tag2>[a-zA-Z0-9-_: .]+)$', 'filters.views.compare_matches'),
-    url(r'^streams/$', 'bundle_stream_list'),
-    url(r'^streams/json$', 'bundle_stream_list_json'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/$', 'bundle_list'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/json$', 'bundle_list_table_json'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/$', 'bundle_detail'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/json$', 'bundle_json'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/$', 'test_run_detail'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/json$', 'test_run_detail_test_json'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/result/(?P<relative_index>[0-9]+)/$', 'test_result_detail'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/hardware-context/$', 'test_run_hardware_context'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)bundles/(?P<content_sha1>[0-9a-z]+)/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/software-context/$', 'test_run_software_context'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)test-runs/$', 'test_run_list'),
-    url(r'^streams(?P<pathname>/[a-zA-Z0-9/._-]+)test-runs/json$', 'test_run_list_json'),
-    url(r'^attachment/(?P<pk>[0-9]+)/download$', 'attachment_download'),
-    url(r'^attachment/(?P<pk>[0-9]+)/view$', 'attachment_view'),
-    url(r'^permalink/test-run/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/$', 'redirect_to_test_run'),
-    url(r'^permalink/test-run/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/(?P<trailing>.*)$', 'redirect_to_test_run'),
-    url(r'^permalink/test-result/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/(?P<relative_index>[0-9]+)/$', 'redirect_to_test_result'),
-    url(r'^permalink/test-result/(?P<analyzer_assigned_uuid>[a-zA-Z0-9-]+)/(?P<relative_index>[0-9]+)/(?P<trailing>.*)$', 'redirect_to_test_result'),
-    url(r'^permalink/bundle/(?P<content_sha1>[0-9a-z]+)/$', 'redirect_to_bundle'),
-    url(r'^permalink/bundle/(?P<content_sha1>[0-9a-z]+)/(?P<trailing>.*)$', 'redirect_to_bundle'),
-    url(r'^image-reports/$', 'images.image_report_list'),
-    url(r'^image-charts/$', 'image_reports.views.image_report_list'),
-    url(r'^image-charts/(?P<name>[a-zA-Z0-9-_]+)$', 'image_reports.views.image_report_detail'),
-    url(r'^image-charts/\+add$', 'image_reports.views.image_report_add'),
-    url(r'^image-charts/(?P<name>[a-zA-Z0-9-_]+)/\+edit$', 'image_reports.views.image_report_edit'),
-    url(r'^image-charts/(?P<name>[a-zA-Z0-9-_]+)/\+publish$', 'image_reports.views.image_report_publish'),
-    url(r'^image-charts/(?P<name>[a-zA-Z0-9-_]+)/\+unpublish$', 'image_reports.views.image_report_unpublish'),
-    url(r'^image-chart/(?P<id>[a-zA-Z0-9-_]+)$', 'image_reports.views.image_chart_detail'),
-    url(r'^image-chart/\+add$', 'image_reports.views.image_chart_add'),
-    url(r'^image-chart/(?P<id>[a-zA-Z0-9-_]+)/\+edit$', 'image_reports.views.image_chart_edit'),
-    url(r'^image-chart/(?P<id>[a-zA-Z0-9-_]+)/\+add-filter$', 'image_reports.views.image_chart_filter_add'),
-    url(r'^image-chart-filter/(?P<id>[a-zA-Z0-9-_]+)$', 'image_reports.views.image_chart_filter_edit'),
-    url(r'^image-chart-filter/(?P<id>[a-zA-Z0-9-_]+)/\+delete$', 'image_reports.views.image_chart_filter_delete'),
-    url(r'^pmqa$', 'pmqa.pmqa_view'),
-    url(r'^pmqa(?P<pathname>/[a-zA-Z0-9/._-]+/)(?P<device_type>[a-zA-Z0-9-_]+)$', 'pmqa.pmqa_filter_view'),
-    url(r'^pmqa(?P<pathname>/[a-zA-Z0-9/._-]+/)(?P<device_type>[a-zA-Z0-9-_]+)/json$', 'pmqa.pmqa_filter_view_json'),
-    url(r'^pmqa(?P<pathname>/[a-zA-Z0-9/._-]+/)(?P<device_type>[a-zA-Z0-9-_]+)/\+compare/(?P<build1>[0-9]+)/(?P<build2>[0-9]+)$', 'pmqa.compare_pmqa_results'),
-    url(r'^image-reports/(?P<name>[A-Za-z0-9_-]+)$', 'images.image_report_detail'),
-    url(r'^api/link-bug-to-testrun', 'images.link_bug_to_testrun'),
-    url(r'^api/unlink-bug-and-testrun', 'images.unlink_bug_and_testrun'),
-    url(r'^test-definition/add_test_definition', 'add_test_definition'),
-    url(r'^test-definition/$', 'test_definition'),
-    url(r'^testdefinition_table_json$', 'testdefinition_table_json'),
-)

=== removed directory 'dashboard_app/views'
=== removed file 'dashboard_app/views/__init__.py'
--- dashboard_app/views/__init__.py	2013-04-01 08:50:05 +0000
+++ dashboard_app/views/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,726 +0,0 @@
-# Copyright (C) 2010-2012 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-Views for the Dashboard application
-"""
-
-import re
-import json
-
-from django.contrib.auth.decorators import login_required
-from django.contrib.sites.models import Site
-from django.core.exceptions import PermissionDenied
-from django.core.urlresolvers import reverse
-from django.db.models.manager import Manager
-from django.db.models.query import QuerySet
-from django.db.models import Count
-from django.http import (
-    Http404,
-    HttpResponse,
-    HttpResponseBadRequest,
-    HttpResponseRedirect,
-    )
-from django.shortcuts import render_to_response, redirect, get_object_or_404
-from django.template import RequestContext, loader
-from django.utils.safestring import mark_safe
-from django.views.generic.list_detail import object_list, object_detail
-from django.forms import ModelForm
-from django import forms
-
-from django_tables2 import Attrs, Column, TemplateColumn
-
-from lava.utils.data_tables.tables import DataTablesTable
-from lava_server.views import index as lava_index
-from lava_server.bread_crumbs import (
-    BreadCrumb,
-    BreadCrumbTrail,
-)
-
-from dashboard_app.models import (
-    Attachment,
-    Bundle,
-    BundleStream,
-    DataReport,
-    DataView,
-    Tag,
-    Test,
-    TestResult,
-    TestRun,
-    TestDefinition,
-)
-
-
-def _get_queryset(klass):
-    """
-    Returns a QuerySet from a Model, Manager, or QuerySet. Created to make
-    get_object_or_404 and get_list_or_404 more DRY.
-    """
-    if isinstance(klass, QuerySet):
-        return klass
-    elif isinstance(klass, Manager):
-        manager = klass
-    else:
-        manager = klass._default_manager
-    return manager.all()
-
-
-def get_restricted_object(klass, via, user, *args, **kwargs):
-    """
-    Uses get() to return an object, or raises a Http404 exception if the object
-    does not exist. If the object exists access control check is made
-    using the via callback (via is called with the found object and the return
-    value must be a RestrictedResource subclass. If the user doesn't have
-    permission to view the resource a 403 error will be displayed.
-
-    klass may be a Model, Manager, or QuerySet object. All other passed
-    arguments and keyword arguments are used in the get() query.
-
-    Note: Like with get(), an MultipleObjectsReturned will be raised if more
-    than one object is found.
-    """
-    queryset = _get_queryset(klass)
-    try:
-        obj = queryset.get(*args, **kwargs)
-        ownership_holder = via(obj)
-        if not ownership_holder.is_accessible_by(user):
-            raise PermissionDenied()
-        return obj
-    except queryset.model.DoesNotExist:
-        raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
-
-
-@BreadCrumb("Dashboard", parent=lava_index)
-def index(request):
-    return render_to_response(
-        "dashboard_app/index.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(index)
-        }, RequestContext(request))
-
-
-
-
-class BundleStreamTable(DataTablesTable):
-
-    pathname = TemplateColumn(
-        '<a href="{% url dashboard_app.views.bundle_list record.pathname %}">'
-        '<code>{{ record.pathname }}</code></a>')
-    name = TemplateColumn(
-        '{{ record.name|default:"<i>not set</i>" }}')
-    number_of_test_runs = TemplateColumn(
-        '<a href="{% url dashboard_app.views.test_run_list record.pathname %}">'
-        '{{ record.get_test_run_count }}')
-    number_of_bundles = TemplateColumn(
-        '<a href="{% url dashboard_app.views.bundle_list record.pathname %}">'
-        '{{ record.bundles.count}}</a>')
-
-    def get_queryset(self, user):
-        return BundleStream.objects.accessible_by_principal(user)
-
-    datatable_opts = {
-        'iDisplayLength': 25,
-        'sPaginationType': "full_numbers",
-        }
-
-    searchable_columns = ['pathname', 'name']
-
-
-def bundle_stream_list_json(request):
-    return BundleStreamTable.json(request, params=(request.user,))
-
-
-@BreadCrumb("Bundle Streams", parent=index)
-def bundle_stream_list(request):
-    """
-    List of bundle streams.
-    """
-    return render_to_response(
-        'dashboard_app/bundle_stream_list.html', {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                bundle_stream_list),
-            "bundle_stream_table": BundleStreamTable(
-                'bundle-stream-table', reverse(bundle_stream_list_json),
-                params=(request.user,)),
-            'has_personal_streams': (
-                request.user.is_authenticated() and
-                BundleStream.objects.filter(user=request.user).count() > 0),
-            'has_team_streams': (
-                request.user.is_authenticated() and
-                BundleStream.objects.filter(
-                    group__in = request.user.groups.all()).count() > 0),
-        }, RequestContext(request)
-    )
-
-
-class BundleTable(DataTablesTable):
-
-    content_filename = TemplateColumn(
-        '<a href="{{ record.get_absolute_url }}">'
-        '<code>{{ record.content_filename }}</code></a>',
-        verbose_name="bundle name")
-
-    passes = TemplateColumn('{{ record.get_summary_results.pass|default:"0" }}')
-    fails = TemplateColumn('{{ record.get_summary_results.fail|default:"0" }}')
-    total_results = TemplateColumn('{{ record.get_summary_results.total }}')
-
-    uploaded_on = TemplateColumn('{{ record.uploaded_on|date:"Y-m-d H:i:s"}}')
-    uploaded_by = TemplateColumn('''
-        {% load i18n %}
-        {% if record.uploaded_by %}
-            {{ record.uploaded_by }}
-        {% else %}
-            <em>{% trans "anonymous user" %}</em>
-        {% endif %}''')
-    deserializaled = TemplateColumn('{{ record.is_deserialized|yesno }}')
-
-    def get_queryset(self, bundle_stream):
-        return bundle_stream.bundles.select_related(
-            'bundle_stream', 'deserialization_error')
-
-    datatable_opts = {
-        'aaSorting': [[4, 'desc']],
-        'sPaginationType': 'full_numbers',
-        'iDisplayLength': 25,
-#        'aLengthMenu': [[10, 25, 50, -1], [10, 25, 50, "All"]],
-        'sDom': 'lfr<"#master-toolbar">t<"F"ip>',
-        }
-
-    searchable_columns = ['content_filename']
-
-
-def bundle_list_table_json(request, pathname):
-    bundle_stream = get_restricted_object(
-        BundleStream,
-        lambda bundle_stream: bundle_stream,
-        request.user,
-        pathname=pathname
-    )
-    return BundleTable.json(request, params=(bundle_stream,))
-
-
-@BreadCrumb(
-    "Bundles in {pathname}",
-    parent=bundle_stream_list,
-    needs=['pathname'])
-def bundle_list(request, pathname):
-    """
-    List of bundles in a specified bundle stream.
-    """
-    bundle_stream = get_restricted_object(
-        BundleStream,
-        lambda bundle_stream: bundle_stream,
-        request.user,
-        pathname=pathname
-    )
-    return render_to_response(
-        "dashboard_app/bundle_list.html",
-        {
-            'bundle_table': BundleTable(
-                'bundle-table',
-                reverse(
-                    bundle_list_table_json, kwargs=dict(pathname=pathname)),
-                params=(bundle_stream,)),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                bundle_list,
-                pathname=pathname),
-            "bundle_stream": bundle_stream
-            },
-        RequestContext(request))
-
-
-@BreadCrumb(
-    "Bundle {content_sha1}",
-    parent=bundle_list,
-    needs=['pathname', 'content_sha1'])
-def bundle_detail(request, pathname, content_sha1):
-    """
-    Detail about a bundle from a particular stream
-    """
-    bundle_stream = get_restricted_object(
-        BundleStream,
-        lambda bundle_stream: bundle_stream,
-        request.user,
-        pathname=pathname
-    )
-    return object_detail(
-        request,
-        queryset=bundle_stream.bundles.all(),
-        slug=content_sha1,
-        slug_field="content_sha1",
-        template_name="dashboard_app/bundle_detail.html",
-        template_object_name="bundle",
-        extra_context={
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                bundle_detail,
-                pathname=pathname,
-                content_sha1=content_sha1),
-            "site": Site.objects.get_current(),
-            "bundle_stream": bundle_stream
-        })
-
-
-def bundle_json(request, pathname, content_sha1):
-    bundle_stream = get_restricted_object(
-        BundleStream,
-        lambda bundle_stream: bundle_stream,
-        request.user,
-        pathname=pathname
-    )
-    bundle = bundle_stream.bundles.get(content_sha1=content_sha1)
-    test_runs = []
-    for test_run in bundle.test_runs.all():
-        results = test_run.get_summary_results()
-
-        measurements = [{'item': str(item.test_case),
-                           'measurement': str(item.measurement),
-                           'units': str(item.units)
-                          }
-                for item in test_run.test_results.filter(
-                            measurement__isnull=False).
-                        order_by('test_case__test_case_id')]
-        results['measurements'] = measurements
-
-        test_runs.append({
-            'name': test_run.test.test_id,
-            'url': request.build_absolute_uri(test_run.get_absolute_url()),
-            'results': results
-            })
-    json_text = json.dumps({
-        'test_runs':test_runs,
-        })
-    content_type = 'application/json'
-    if 'callback' in request.GET:
-        json_text = '%s(%s)'%(request.GET['callback'], json_text)
-        content_type = 'text/javascript'
-    return HttpResponse(json_text, content_type=content_type)
-
-
-def ajax_bundle_viewer(request, pk):
-    bundle = get_restricted_object(
-        Bundle,
-        lambda bundle: bundle.bundle_stream,
-        request.user,
-        pk=pk
-    )
-    return render_to_response(
-        "dashboard_app/_ajax_bundle_viewer.html", {
-            "bundle": bundle
-        },
-        RequestContext(request))
-
-
-class TestRunTable(DataTablesTable):
-
-    record = TemplateColumn(
-        '<a href="{{ record.get_absolute_url }}">'
-        '<code>{{ record.test }} results<code/></a>',
-        accessor="test__test_id",
-        )
-
-    test = TemplateColumn(
-        '<a href="{{ record.test.get_absolute_url }}">{{ record.test }}</a>',
-        accessor="test__test_id",
-        )
-
-    uploaded_on = TemplateColumn(
-        '{{ record.bundle.uploaded_on|date:"Y-m-d H:i:s" }}',
-        accessor='bundle__uploaded_on')
-
-    analyzed_on = TemplateColumn(
-        '{{ record.analyzer_assigned_date|date:"Y-m-d H:i:s" }}',
-        accessor='analyzer_assigned_date')
-
-    def get_queryset(self, bundle_stream):
-        return TestRun.objects.filter(
-                bundle__bundle_stream=bundle_stream
-            ).select_related(
-                "test",
-                "bundle",
-                "bundle__bundle_stream",
-                "test_results"
-            ).only(
-                "analyzer_assigned_uuid",  # needed by TestRun.__unicode__
-                "analyzer_assigned_date",  # used by the view
-                "bundle__uploaded_on",  # needed by Bundle.get_absolute_url
-                "bundle__content_sha1",   # needed by Bundle.get_absolute_url
-                "bundle__bundle_stream__pathname",  # Needed by TestRun.get_absolute_url
-                "test__name",  # needed by Test.__unicode__
-                "test__test_id",  # needed by Test.__unicode__
-            )
-
-    datatable_opts = {
-        "sPaginationType": "full_numbers",
-        "aaSorting": [[1, "desc"]],
-        "iDisplayLength": 25,
-        "sDom": 'lfr<"#master-toolbar">t<"F"ip>'
-        }
-
-    searchable_columns = ['test__test_id']
-
-
-def test_run_list_json(request, pathname):
-    bundle_stream = get_restricted_object(
-        BundleStream,
-        lambda bundle_stream: bundle_stream,
-        request.user,
-        pathname=pathname
-    )
-    return TestRunTable.json(request, params=(bundle_stream,))
-
-
-@BreadCrumb(
-    "Test runs in {pathname}",
-    parent=bundle_stream_list,
-    needs=['pathname'])
-def test_run_list(request, pathname):
-    """
-    List of test runs in a specified bundle stream.
-    """
-    bundle_stream = get_restricted_object(
-        BundleStream,
-        lambda bundle_stream: bundle_stream,
-        request.user,
-        pathname=pathname
-    )
-    return render_to_response(
-        'dashboard_app/test_run_list.html', {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                test_run_list,
-                pathname=pathname),
-            "test_run_table": TestRunTable(
-                'test-runs',
-                reverse(test_run_list_json, kwargs=dict(pathname=pathname)),
-                params=(bundle_stream,)),
-            "bundle_stream": bundle_stream,
-        }, RequestContext(request)
-    )
-
-
-class TestTable(DataTablesTable):
-
-    relative_index = Column(
-        verbose_name="#", attrs=Attrs(th=dict(style="width: 1%")),
-        default=mark_safe("<em>Not specified</em>"))
-
-    test_case = Column()
-
-    result = TemplateColumn('''
-        <a href="{{record.get_absolute_url}}">
-          <img src="{{ STATIC_URL }}dashboard_app/images/icon-{{ record.result_code }}.png"
-          alt="{{ record.result_code }}" width="16" height="16" border="0"/>{{ record.result_code }}
-        {% if record.attachments__count %}
-        <a href="{{record.get_absolute_url}}#attachments">
-          <img style="float:right;" src="{{ STATIC_URL }}dashboard_app/images/attachment.png"
-               alt="This result has {{ record.attachments__count }} attachments"
-               title="This result has {{ record.attachments__count }} attachments"
-               /></a>
-        {% endif %}
-        ''')
-
-    units = TemplateColumn(
-        '{{ record.measurement|default_if_none:"Not specified" }} {{ record.units }}',
-        verbose_name="measurement")
-
-    def get_queryset(self, test_run):
-        return test_run.get_results().annotate(Count("attachments"))
-
-    datatable_opts = {
-        'sPaginationType': "full_numbers",
-        'iDisplayLength': 25,
-        }
-
-    searchable_columns = ['test_case__test_case_id']
-
-
-
-def test_run_detail_test_json(request, pathname, content_sha1, analyzer_assigned_uuid):
-    test_run = get_restricted_object(
-        TestRun, lambda test_run: test_run.bundle.bundle_stream,
-        request.user,
-        analyzer_assigned_uuid=analyzer_assigned_uuid
-        )
-    return TestTable.json(request, params=(test_run,))
-
-
-@BreadCrumb(
-    "Run {analyzer_assigned_uuid}",
-    parent=bundle_detail,
-    needs=['pathname', 'content_sha1', 'analyzer_assigned_uuid'])
-def test_run_detail(request, pathname, content_sha1, analyzer_assigned_uuid):
-    test_run = get_restricted_object(
-        TestRun,
-        lambda test_run: test_run.bundle.bundle_stream,
-        request.user,
-        analyzer_assigned_uuid=analyzer_assigned_uuid
-    )
-    return render_to_response(
-        "dashboard_app/test_run_detail.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                test_run_detail,
-                pathname=pathname,
-                content_sha1=content_sha1,
-                analyzer_assigned_uuid=analyzer_assigned_uuid),
-            "test_run": test_run,
-            "test_table": TestTable(
-                'test-table',
-                reverse(test_run_detail_test_json, kwargs=dict(
-                    pathname=pathname,
-                    content_sha1=content_sha1,
-                    analyzer_assigned_uuid=analyzer_assigned_uuid)),
-                params=(test_run,))
-
-        }, RequestContext(request))
-
-
-@BreadCrumb(
-    "Software Context",
-    parent=test_run_detail,
-    needs=['pathname', 'content_sha1', 'analyzer_assigned_uuid'])
-def test_run_software_context(request, pathname, content_sha1, analyzer_assigned_uuid):
-    test_run = get_restricted_object(
-        TestRun,
-        lambda test_run: test_run.bundle.bundle_stream,
-        request.user,
-        analyzer_assigned_uuid=analyzer_assigned_uuid
-    )
-    return render_to_response(
-        "dashboard_app/test_run_software_context.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                test_run_software_context,
-                pathname=pathname,
-                content_sha1=content_sha1,
-                analyzer_assigned_uuid=analyzer_assigned_uuid),
-            "test_run": test_run
-        }, RequestContext(request))
-
-
-@BreadCrumb(
-    "Hardware Context",
-    parent=test_run_detail,
-    needs=['pathname', 'content_sha1', 'analyzer_assigned_uuid'])
-def test_run_hardware_context(request, pathname, content_sha1, analyzer_assigned_uuid):
-    test_run = get_restricted_object(
-        TestRun,
-        lambda test_run: test_run.bundle.bundle_stream,
-        request.user,
-        analyzer_assigned_uuid=analyzer_assigned_uuid
-    )
-    return render_to_response(
-        "dashboard_app/test_run_hardware_context.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                test_run_hardware_context,
-                pathname=pathname,
-                content_sha1=content_sha1,
-                analyzer_assigned_uuid=analyzer_assigned_uuid),
-            "test_run": test_run
-        }, RequestContext(request))
-
-
-@BreadCrumb(
-    "Details of result {relative_index}",
-    parent=test_run_detail,
-    needs=['pathname', 'content_sha1', 'analyzer_assigned_uuid', 'relative_index'])
-def test_result_detail(request, pathname, content_sha1, analyzer_assigned_uuid, relative_index):
-    test_run = get_restricted_object(
-        TestRun,
-        lambda test_run: test_run.bundle.bundle_stream,
-        request.user,
-        analyzer_assigned_uuid=analyzer_assigned_uuid
-    )
-    test_result = test_run.test_results.select_related('fig').get(relative_index=relative_index)
-    return render_to_response(
-        "dashboard_app/test_result_detail.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                test_result_detail,
-                pathname=pathname,
-                content_sha1=content_sha1,
-                analyzer_assigned_uuid=analyzer_assigned_uuid,
-                relative_index=relative_index),
-            "test_result": test_result
-        }, RequestContext(request))
-
-
-def attachment_download(request, pk):
-    attachment = get_restricted_object(
-        Attachment,
-        lambda attachment: attachment.bundle.bundle_stream,
-        request.user,
-        pk = pk
-    )
-    if not attachment.content:
-        return HttpResponseBadRequest(
-            "Attachment %s not present on dashboard" % pk)
-    response = HttpResponse(mimetype=attachment.mime_type)
-    response['Content-Disposition'] = 'attachment; filename=%s' % (
-                                       attachment.content_filename)
-    response.write(attachment.content.read())
-    return response
-
-
-def attachment_view(request, pk):
-    attachment = get_restricted_object(
-        Attachment,
-        lambda attachment: attachment.bundle.bundle_stream,
-        request.user,
-        pk = pk
-    )
-    if not attachment.content or not attachment.is_viewable():
-        return HttpResponseBadRequest("Attachment %s not viewable" % pk)
-    return render_to_response(
-        "dashboard_app/attachment_view.html", {
-            'attachment': attachment,
-        }, RequestContext(request))
-
-
-@BreadCrumb("Reports", parent=index)
-def report_list(request):
-    return render_to_response(
-        "dashboard_app/report_list.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(report_list),
-            "report_list": DataReport.repository.all()
-        }, RequestContext(request))
-
-
-@BreadCrumb("{title}", parent=report_list, needs=['name'])
-def report_detail(request, name):
-    try:
-        report = DataReport.repository.get(name=name)
-    except DataReport.DoesNotExist:
-        raise Http404('No report matches given name.')
-    return render_to_response(
-        "dashboard_app/report_detail.html", {
-            "is_iframe": request.GET.get("iframe") == "yes",
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                report_detail,
-                name=report.name,
-                title=report.title),
-            "report": report,
-        }, RequestContext(request))
-
-
-@BreadCrumb("Data views", parent=index)
-def data_view_list(request):
-    return render_to_response(
-        "dashboard_app/data_view_list.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(data_view_list),
-            "data_view_list": DataView.repository.all(),
-        }, RequestContext(request))
-
-
-@BreadCrumb(
-    "Details of {name}",
-    parent=data_view_list,
-    needs=['name'])
-def data_view_detail(request, name):
-    try:
-        data_view = DataView.repository.get(name=name)
-    except DataView.DoesNotExist:
-        raise Http404('No data view matches the given query.')
-    return render_to_response(
-        "dashboard_app/data_view_detail.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                data_view_detail,
-                name=data_view.name,
-                summary=data_view.summary),
-            "data_view": data_view
-        }, RequestContext(request))
-
-
-def redirect_to(request, object, trailing):
-    url = object.get_absolute_url() + trailing
-    qs = request.META.get('QUERY_STRING')
-    if qs:
-        url += '?' + qs
-    return redirect(url)
-
-
-def redirect_to_test_run(request, analyzer_assigned_uuid, trailing=''):
-    test_run = get_restricted_object(
-        TestRun,
-        lambda test_run: test_run.bundle.bundle_stream,
-        request.user,
-        analyzer_assigned_uuid=analyzer_assigned_uuid)
-    return redirect_to(request, test_run, trailing)
-
-
-def redirect_to_test_result(request, analyzer_assigned_uuid, relative_index,
-                            trailing=''):
-    test_result = get_restricted_object(
-        TestResult,
-        lambda test_result: test_result.test_run.bundle.bundle_stream,
-        request.user,
-        test_run__analyzer_assigned_uuid=analyzer_assigned_uuid,
-        relative_index=relative_index)
-    return redirect_to(request, test_result, trailing)
-
-
-def redirect_to_bundle(request, content_sha1, trailing=''):
-    bundle = get_restricted_object(
-        Bundle,
-        lambda bundle: bundle.bundle_stream,
-        request.user,
-        content_sha1=content_sha1)
-    return redirect_to(request, bundle, trailing)
-
-
-class TestDefinitionTable(DataTablesTable):
-    name = Column()
-    version = Column()
-    location = Column()
-    description = Column()
-    def get_queryset(self):
-        return TestDefinition.objects.all()
-
-
-def testdefinition_table_json(request):
-    return TestDefinitionTable.json(request)
-
-
-@BreadCrumb("Test Definitions", parent=index)
-def test_definition(request):
-    return render_to_response(
-        "dashboard_app/test_definition.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(test_definition),
-            "testdefinition_table": TestDefinitionTable(
-                'testdeflist',
-                reverse(testdefinition_table_json))
-        }, RequestContext(request))
-
-
-class AddTestDefForm(ModelForm):
-    class Meta:
-        model = TestDefinition
-        fields = ('name', 'version', 'description', 'format', 'location',
-                  'url', 'environment', 'target_os', 'target_dev_types',
-                  'content', 'mime_type')
-
-@BreadCrumb("Add Test Definition", parent=index)
-def add_test_definition(request):
-    if request.method == 'POST':
-        form = AddTestDefForm(request.POST)
-        if form.is_valid():
-            form.save()
-            return HttpResponseRedirect('/dashboard/test-definition/')
-    else:
-        form = AddTestDefForm()
-    return render_to_response(
-        "dashboard_app/add_test_definition.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                add_test_definition),
-            "form": form,
-            }, RequestContext(request))

=== removed directory 'dashboard_app/views/filters'
=== removed file 'dashboard_app/views/filters/__init__.py'
--- dashboard_app/views/filters/__init__.py	2012-10-01 03:34:07 +0000
+++ dashboard_app/views/filters/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-# Copyright (C) 2010-2011 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.

=== removed file 'dashboard_app/views/filters/forms.py'
--- dashboard_app/views/filters/forms.py	2013-01-09 00:14:58 +0000
+++ dashboard_app/views/filters/forms.py	1970-01-01 00:00:00 +0000
@@ -1,242 +0,0 @@
-# Copyright (C) 2010-2011 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-from django.conf import settings
-from django.contrib.admin.widgets import FilteredSelectMultiple
-from django.core.exceptions import ValidationError
-from django import forms
-from django.forms.formsets import BaseFormSet, formset_factory
-from django.forms.widgets import Select
-from django.template import Template, Context
-from django.utils.safestring import mark_safe
-
-from dashboard_app.models import (
-    BundleStream,
-    Test,
-    TestCase,
-    TestRunFilter,
-    TestRunFilterSubscription,
-)
-
-class TestRunFilterSubscriptionForm(forms.ModelForm):
-    class Meta:
-        model = TestRunFilterSubscription
-        fields = ('level',)
-    def __init__(self, filter, user, *args, **kwargs):
-        super(TestRunFilterSubscriptionForm, self).__init__(*args, **kwargs)
-        self.instance.filter = filter
-        self.instance.user = user
-
-
-
-test_run_filter_head = '''
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/filter-edit.css" />
-<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}dashboard_app/css/wider-filter-horizontal.css" />
-<script type="text/javascript" src="{% url admin:jsi18n %}"></script>
-<script type="text/javascript">
-var django = {};
-django.jQuery = $;
-var test_case_url = "{% url dashboard_app.views.filters.views.filter_add_cases_for_test_json %}?test=";
-var attr_name_completion_url = "{% url dashboard_app.views.filters.views.filter_attr_name_completion_json %}";
-var attr_value_completion_url = "{% url dashboard_app.views.filters.views.filter_attr_value_completion_json %}";
-</script>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/jquery.formset.js"></script>
-<script type="text/javascript" src="{{ STATIC_URL }}dashboard_app/js/filter-edit.js"></script>
-'''
-
-
-class AttributesForm(forms.Form):
-    name = forms.CharField(max_length=1024)
-    value = forms.CharField(max_length=1024)
-
-AttributesFormSet = formset_factory(AttributesForm, extra=0)
-
-
-class TruncatingSelect(Select):
-
-    def render_option(self, selected_choices, option_value, option_label):
-        if len(option_label) > 50:
-            option_label = option_label[:50] + '...'
-        return super(TruncatingSelect, self).render_option(
-            selected_choices, option_value, option_label)
-
-
-class TRFTestCaseForm(forms.Form):
-
-    test_case = forms.ModelChoiceField(
-        queryset=TestCase.objects.none(), widget=TruncatingSelect, empty_label=None)
-
-
-class BaseTRFTestCaseFormSet(BaseFormSet):
-
-    def __init__(self, *args, **kw):
-        self._queryset = kw.pop('queryset')
-        super(BaseTRFTestCaseFormSet, self).__init__(*args, **kw)
-
-    def add_fields(self, form, index):
-        super(BaseTRFTestCaseFormSet, self).add_fields(form, index)
-        if self._queryset is not None:
-            form.fields['test_case'].queryset = self._queryset
-
-
-TRFTestCaseFormSet = formset_factory(
-    TRFTestCaseForm, extra=0, formset=BaseTRFTestCaseFormSet)
-
-
-class TRFTestForm(forms.Form):
-
-    def __init__(self, *args, **kw):
-        super(TRFTestForm, self).__init__(*args, **kw)
-        kw['initial'] = kw.get('initial', {}).get('test_cases', None)
-        kw.pop('empty_permitted', None)
-        kw['queryset'] = None
-        v = self['test'].value()
-        if v:
-            test = self.fields['test'].to_python(v)
-            queryset = TestCase.objects.filter(test=test).order_by('test_case_id')
-            kw['queryset'] = queryset
-        self.test_case_formset = TRFTestCaseFormSet(*args, **kw)
-
-    def is_valid(self):
-        return super(TRFTestForm, self).is_valid() and \
-               self.test_case_formset.is_valid()
-
-    def full_clean(self):
-        super(TRFTestForm, self).full_clean()
-        self.test_case_formset.full_clean()
-
-    test = forms.ModelChoiceField(
-        queryset=Test.objects.order_by('test_id'), required=True)
-
-
-class BaseTRFTestsFormSet(BaseFormSet):
-
-    def is_valid(self):
-        if not super(BaseTRFTestsFormSet, self).is_valid():
-            return False
-        for form in self.forms:
-            if not form.is_valid():
-                return False
-        return True
-
-
-TRFTestsFormSet = formset_factory(
-    TRFTestForm, extra=0, formset=BaseTRFTestsFormSet)
-
-
-class TestRunFilterForm(forms.ModelForm):
-    class Meta:
-        model = TestRunFilter
-        exclude = ('owner',)
-        widgets = {
-            'bundle_streams': FilteredSelectMultiple("Bundle Streams", False),
-            }
-
-    @property
-    def media(self):
-        super_media = str(super(TestRunFilterForm, self).media)
-        return mark_safe(Template(test_run_filter_head).render(
-            Context({'STATIC_URL': settings.STATIC_URL})
-            )) + super_media
-
-    def validate_name(self, value):
-        self.instance.name = value
-        try:
-            self.instance.validate_unique()
-        except ValidationError, e:
-            if e.message_dict.values() == [[
-                u'Test run filter with this Owner and Name already exists.']]:
-                raise ValidationError("You already have a filter with this name")
-            else:
-                raise
-
-    def save(self, commit=True, **kwargs):
-        instance = super(TestRunFilterForm, self).save(commit=commit, **kwargs)
-        if commit:
-            instance.attributes.all().delete()
-            for a in self.attributes_formset.cleaned_data:
-                instance.attributes.create(name=a['name'], value=a['value'])
-            instance.tests.all().delete()
-            for i, test_form in enumerate(self.tests_formset.forms):
-                trf_test = instance.tests.create(
-                    test=test_form.cleaned_data['test'], index=i)
-                for j, test_case_form in enumerate(test_form.test_case_formset.forms):
-                    trf_test.cases.create(
-                        test_case=test_case_form.cleaned_data['test_case'], index=j)
-        return instance
-
-    def is_valid(self):
-        return super(TestRunFilterForm, self).is_valid() and \
-               self.attributes_formset.is_valid() and \
-               self.tests_formset.is_valid()
-
-    def full_clean(self):
-        super(TestRunFilterForm, self).full_clean()
-        self.attributes_formset.full_clean()
-        self.tests_formset.full_clean()
-
-    def as_data(self):
-        assert self.is_valid(), self.errors
-        data = self.cleaned_data.copy()
-        tests = []
-        for form in self.tests_formset.forms:
-            tests.append({
-                'test': form.cleaned_data['test'],
-                'test_cases': [
-                    tc_form.cleaned_data['test_case']
-                    for tc_form in form.test_case_formset]
-                    })
-        data['attributes'] = [
-            (d['name'], d['value']) for d in self.attributes_formset.cleaned_data]
-        data['tests'] = tests
-        data['uploaded_by'] = None
-        return data
-
-    def __init__(self, user, *args, **kwargs):
-        super(TestRunFilterForm, self).__init__(*args, **kwargs)
-        self.instance.owner = user
-        kwargs.pop('instance', None)
-
-        attr_set_args = kwargs.copy()
-        if self.instance.pk:
-            initial = []
-            for attr in self.instance.attributes.all():
-                initial.append({
-                    'name': attr.name,
-                    'value': attr.value,
-                    })
-            attr_set_args['initial'] = initial
-        attr_set_args['prefix'] = 'attributes'
-        self.attributes_formset = AttributesFormSet(*args, **attr_set_args)
-
-        tests_set_args = kwargs.copy()
-        if self.instance.pk:
-            initial = []
-            for test in self.instance.tests.all().order_by('index').prefetch_related('cases'):
-                initial.append({
-                    'test': test.test,
-                    'test_cases': [{'test_case': unicode(tc.test_case.id)} for tc in test.cases.all().order_by('index')],
-                    })
-            tests_set_args['initial'] = initial
-        tests_set_args['prefix'] = 'tests'
-        self.tests_formset = TRFTestsFormSet(*args, **tests_set_args)
-
-        self.fields['bundle_streams'].queryset = \
-            BundleStream.objects.accessible_by_principal(user).order_by('pathname')
-        self.fields['name'].validators.append(self.validate_name)
-

=== removed file 'dashboard_app/views/filters/tables.py'
--- dashboard_app/views/filters/tables.py	2013-09-09 11:47:00 +0000
+++ dashboard_app/views/filters/tables.py	1970-01-01 00:00:00 +0000
@@ -1,268 +0,0 @@
-# Copyright (C) 2010-2011 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-import datetime
-import operator
-
-from django.conf import settings
-from django.template import defaultfilters
-from django.utils.html import escape
-from django.utils.safestring import mark_safe
-
-from django_tables2 import Column, TemplateColumn
-
-from lava.utils.data_tables.tables import DataTablesTable
-
-from dashboard_app.filters import evaluate_filter
-from dashboard_app.models import (
-    TestRunFilter,
-    TestRunFilterSubscription,
-    )
-
-class UserFiltersTable(DataTablesTable):
-
-    name = TemplateColumn('''
-    <a href="{{ record.get_absolute_url }}">{{ record.name }}</a>
-    ''')
-
-    bundle_streams = TemplateColumn('''
-    {% for r in record.bundle_streams.all %}
-        {{r.pathname}} <br />
-    {% endfor %}
-    ''')
-
-    build_number_attribute = Column()
-    def render_build_number_attribute(self, value):
-        if not value:
-            return ''
-        return value
-
-    attributes = TemplateColumn('''
-    {% for a in record.attributes.all %}
-    {{ a }}  <br />
-    {% endfor %}
-    ''')
-
-    test = TemplateColumn('''
-      <table style="border-collapse: collapse">
-        <tbody>
-          {% for trftest in record.tests.all %}
-          <tr>
-            <td>
-              {{ trftest.test }}
-            </td>
-            <td>
-              {% for trftest_case in trftest.cases.all %}
-              {{ trftest_case.test_case.test_case_id }}
-              {% empty %}
-              <i>any</i>
-              {% endfor %}
-            </td>
-          </tr>
-          {% endfor %}
-        </tbody>
-      </table>
-    ''')
-
-    subscription = Column()
-    def render_subscription(self, record):
-        try:
-            sub = TestRunFilterSubscription.objects.get(
-                user=self.user, filter=record)
-        except TestRunFilterSubscription.DoesNotExist:
-            return "None"
-        else:
-            return sub.get_level_display()
-
-    public = Column()
-
-    def get_queryset(self, user):
-        return TestRunFilter.objects.filter(owner=user)
-
-
-class PublicFiltersTable(UserFiltersTable):
-
-    name = TemplateColumn('''
-    <a href="{{ record.get_absolute_url }}">~{{ record.owner.username }}/{{ record.name }}</a>
-    ''')
-
-    def __init__(self, *args, **kw):
-        super(PublicFiltersTable, self).__init__(*args, **kw)
-        del self.base_columns['public']
-
-    def get_queryset(self):
-        return TestRunFilter.objects.filter(public=True)
-
-
-class AllFiltersSimpleTable(DataTablesTable):
-
-    name = TemplateColumn('''
-    <a href="#" onclick="filters_callback('{{ record.id }}', '{{ record.name }}');">{{ record.name }}</a>
-    ''')
-
-    def get_queryset(self):
-        return TestRunFilter.objects.all()
-
-
-class TestRunColumn(Column):
-    def render(self, record):
-        # This column is only rendered if we don't really expect
-        # record.test_runs to be very long...
-        links = []
-        trs = [tr for tr in record.test_runs if tr.test.test_id == self.verbose_name]
-        for tr in trs:
-            text = '%s / %s' % (tr.denormalization.count_pass, tr.denormalization.count_all())
-            links.append('<a href="%s">%s</a>' % (tr.get_absolute_url(), text))
-        return mark_safe('&nbsp;'.join(links))
-
-
-class SpecificCaseColumn(Column):
-    def __init__(self, test_case, verbose_name=None):
-        if verbose_name is None:
-            verbose_name = mark_safe(test_case.test_case_id)
-        super(SpecificCaseColumn, self).__init__(verbose_name)
-        self.test_case = test_case
-    def render(self, record):
-        r = []
-        for result in record.specific_results:
-            if result.test_case_id != self.test_case.id:
-                continue
-            if result.result == result.RESULT_PASS and result.units:
-                s = '%s %s' % (result.measurement, result.units)
-            else:
-                s = result.RESULT_MAP[result.result]
-            r.append('<a href="' + result.get_absolute_url() + '">'+escape(s)+'</a>')
-        return mark_safe(', '.join(r))
-
-
-class BundleColumn(Column):
-    def render(self, record):
-        return mark_safe('<a href="' + record.bundle.get_absolute_url() + '">' + escape(record.bundle.content_filename) + '</a>')
-
-
-class FilterTable(DataTablesTable):
-    def __init__(self, *args, **kwargs):
-        kwargs['template'] = 'dashboard_app/filter_results_table.html'
-        super(FilterTable, self).__init__(*args, **kwargs)
-        match_maker = self.data.queryset
-        self.base_columns['tag'].verbose_name = match_maker.key_name
-        bundle_stream_col = self.base_columns.pop('bundle_stream')
-        bundle_col = self.base_columns.pop('bundle')
-        tag_col = self.base_columns.pop('tag')
-        self.complex_header = False
-        if match_maker.filter_data['tests']:
-            del self.base_columns['passes']
-            del self.base_columns['total']
-            for i, t in enumerate(reversed(match_maker.filter_data['tests'])):
-                if len(t['test_cases']) == 0:
-                    col = TestRunColumn(mark_safe(t['test'].test_id))
-                    self.base_columns.insert(0, 'test_run_%s' % i, col)
-                elif len(t['test_cases']) == 1:
-                    tc = t['test_cases'][0]
-                    n = t['test'].test_id + ':' + tc.test_case_id
-                    col = SpecificCaseColumn(tc, n)
-                    self.base_columns.insert(0, 'test_run_%s_case' % i, col)
-                else:
-                    col0 = SpecificCaseColumn(t['test_cases'][0])
-                    col0.in_group = True
-                    col0.first_in_group = True
-                    col0.group_length = len(t['test_cases'])
-                    col0.group_name = mark_safe(t['test'].test_id)
-                    self.complex_header = True
-                    self.base_columns.insert(0, 'test_run_%s_case_%s' % (i, 0), col0)
-                    for j, tc in enumerate(t['test_cases'][1:], 1):
-                        col = SpecificCaseColumn(tc)
-                        col.in_group = True
-                        col.first_in_group = False
-                        self.base_columns.insert(j, 'test_run_%s_case_%s' % (i, j), col)
-        else:
-            self.base_columns.insert(0, 'bundle', bundle_col)
-        if len(match_maker.filter_data['bundle_streams']) > 1:
-            self.base_columns.insert(0, 'bundle_stream', bundle_stream_col)
-        self.base_columns.insert(0, 'tag', tag_col)
-
-    def render_tag(self, value):
-        if isinstance(value, datetime.datetime):
-            strvalue = defaultfilters.date(value, settings.DATETIME_FORMAT)
-        else:
-            strvalue = value
-        return mark_safe('<span data-machinetag="%s">%s</span>' % (escape(str(value)), strvalue))
-    tag = Column()
-
-    def render_bundle_stream(self, record):
-        bundle_streams = set(tr.bundle.bundle_stream for tr in record.test_runs)
-        links = []
-        for bs in sorted(bundle_streams, key=operator.attrgetter('pathname')):
-            links.append('<a href="%s">%s</a>' % (
-                bs.get_absolute_url(), escape(bs.pathname)))
-        return mark_safe('<br />'.join(links))
-    bundle_stream = Column(mark_safe("Bundle Stream(s)"))
-
-    def render_bundle(self, record):
-        bundles = set(tr.bundle for tr in record.test_runs)
-        links = []
-        for b in sorted(bundles, key=operator.attrgetter('uploaded_on')):
-            links.append('<a href="%s">%s</a>' % (
-                b.get_absolute_url(), escape(b.content_filename)))
-        return mark_safe('<br />'.join(links))
-    bundle = Column(mark_safe("Bundle(s)"))
-
-    passes = Column(accessor='pass_count')
-    total = Column(accessor='result_count')
-
-    def get_queryset(self, user, filter_data):
-        return evaluate_filter(user, filter_data)
-
-    datatable_opts = {
-        "sPaginationType": "full_numbers",
-        "iDisplayLength": 25,
-        "bSort": False,
-        }
-
-
-class FilterPreviewTable(FilterTable):
-    datatable_opts = FilterTable.datatable_opts.copy()
-    datatable_opts.update({
-        "iDisplayLength": 10,
-        })
-
-
-class TestResultDifferenceTable(DataTablesTable):
-    test_case_id = Column(verbose_name=mark_safe('test_case_id'))
-    first_result = TemplateColumn('''
-    {% if record.first_result %}
-    <img src="{{ STATIC_URL }}dashboard_app/images/icon-{{ record.first_result }}.png"
-          alt="{{ record.first_result }}" width="16" height="16" border="0"/>{{ record.first_result }}
-    {% else %}
-    <i>missing</i>
-    {% endif %}
-        ''')
-    second_result = TemplateColumn('''
-    {% if record.second_result %}
-    <img src="{{ STATIC_URL }}dashboard_app/images/icon-{{ record.second_result }}.png"
-          alt="{{ record.second_result }}" width="16" height="16" border="0"/>{{ record.second_result }}
-    {% else %}
-    <i>missing</i>
-    {% endif %}
-        ''')
-
-    datatable_opts = {
-        'iDisplayLength': 25,
-        'sPaginationType': "full_numbers",
-        }
-

=== removed file 'dashboard_app/views/filters/views.py'
--- dashboard_app/views/filters/views.py	2013-09-09 11:47:00 +0000
+++ dashboard_app/views/filters/views.py	1970-01-01 00:00:00 +0000
@@ -1,425 +0,0 @@
-# Copyright (C) 2010-2011 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-import json
-
-from django.contrib.auth.decorators import login_required
-from django.contrib.contenttypes.models import ContentType
-from django.core import serializers
-from django.core.exceptions import PermissionDenied, ValidationError
-from django.core.urlresolvers import reverse
-from django.http import HttpResponse, HttpResponseRedirect
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-from django.utils.html import escape
-from django.utils.safestring import mark_safe
-
-from lava_server.bread_crumbs import (
-    BreadCrumb,
-    BreadCrumbTrail,
-)
-
-from dashboard_app.filters import (
-    evaluate_filter,
-    )
-from dashboard_app.models import (
-    Bundle,
-    NamedAttribute,
-    Test,
-    TestCase,
-    TestRun,
-    TestRunFilter,
-    TestRunFilterSubscription,
-    )
-from dashboard_app.views import (
-    index,
-    )
-from dashboard_app.views.filters.forms import (
-    TestRunFilterForm,
-    TestRunFilterSubscriptionForm,
-    )
-from dashboard_app.views.filters.tables import (
-    FilterTable,
-    FilterPreviewTable,
-    PublicFiltersTable,
-    TestResultDifferenceTable,
-    UserFiltersTable,
-    )
-
-
-@BreadCrumb("Filters and Subscriptions", parent=index)
-def filters_list(request):
-    public_filters_table = PublicFiltersTable("public-filters", None)
-    if request.user.is_authenticated():
-        public_filters_table.user = request.user
-        user_filters_table = UserFiltersTable("user-filters", None, params=(request.user,))
-        user_filters_table.user = request.user
-    else:
-        user_filters_table = None
-        del public_filters_table.base_columns['subscription']
-
-    return render_to_response(
-        'dashboard_app/filters_list.html', {
-            'user_filters_table': user_filters_table,
-            'public_filters_table': public_filters_table,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                filters_list),
-        }, RequestContext(request)
-    )
-
-
-def filter_json(request, username, name):
-    filter = TestRunFilter.objects.get(owner__username=username, name=name)
-    return FilterTable.json(request, params=(request.user, filter.as_data()))
-
-
-
-def filter_preview_json(request):
-    try:
-        filter = TestRunFilter.objects.get(owner=request.user, name=request.GET['name'])
-    except TestRunFilter.DoesNotExist:
-        filter = None
-    form = TestRunFilterForm(request.user, request.GET, instance=filter)
-    if not form.is_valid():
-        raise ValidationError(str(form.errors))
-    return FilterPreviewTable.json(request, params=(request.user, form.as_data()))
-
-
-@BreadCrumb("Filter ~{username}/{name}", parent=filters_list, needs=['username', 'name'])
-def filter_detail(request, username, name):
-    filter = TestRunFilter.objects.get(owner__username=username, name=name)
-    if not filter.public and filter.owner != request.user:
-        raise PermissionDenied()
-    if not request.user.is_authenticated():
-        subscription = None
-    else:
-        try:
-            subscription = TestRunFilterSubscription.objects.get(
-                user=request.user, filter=filter)
-        except TestRunFilterSubscription.DoesNotExist:
-            subscription = None
-    return render_to_response(
-        'dashboard_app/filter_detail.html', {
-            'filter': filter,
-            'subscription': subscription,
-            'filter_table': FilterTable(
-                "filter-table",
-                reverse(filter_json, kwargs=dict(username=username, name=name)),
-                params=(request.user, filter.as_data())),
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                filter_detail, name=name, username=username),
-        }, RequestContext(request)
-    )
-
-
-@BreadCrumb("Manage Subscription", parent=filter_detail, needs=['name', 'username'])
-@login_required
-def filter_subscribe(request, username, name):
-    filter = TestRunFilter.objects.get(owner__username=username, name=name)
-    if not filter.public and filter.owner != request.user:
-        raise PermissionDenied()
-    try:
-        subscription = TestRunFilterSubscription.objects.get(
-            user=request.user, filter=filter)
-    except TestRunFilterSubscription.DoesNotExist:
-        subscription = None
-    if request.method == "POST":
-        form = TestRunFilterSubscriptionForm(
-            filter, request.user, request.POST, instance=subscription)
-        if form.is_valid():
-            if 'unsubscribe' in request.POST:
-                subscription.delete()
-            else:
-                form.save()
-            return HttpResponseRedirect(filter.get_absolute_url())
-    else:
-        form = TestRunFilterSubscriptionForm(
-            filter, request.user, instance=subscription)
-    return render_to_response(
-        'dashboard_app/filter_subscribe.html', {
-            'filter': filter,
-            'form': form,
-            'subscription': subscription,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                filter_subscribe, name=name, username=username),
-        }, RequestContext(request)
-    )
-
-
-def filter_form(request, bread_crumb_trail, instance=None):
-    if request.method == 'POST':
-        form = TestRunFilterForm(request.user, request.POST, instance=instance)
-
-        if form.is_valid():
-            if 'save' in request.POST:
-                filter = form.save()
-                return HttpResponseRedirect(filter.get_absolute_url())
-            else:
-                c = request.POST.copy()
-                c.pop('csrfmiddlewaretoken', None)
-                return render_to_response(
-                    'dashboard_app/filter_preview.html', {
-                        'bread_crumb_trail': bread_crumb_trail,
-                        'form': form,
-                        'table': FilterPreviewTable(
-                            'filter-preview',
-                            reverse(filter_preview_json) + '?' + c.urlencode(),
-                            params=(request.user, form.as_data())),
-                    }, RequestContext(request))
-    else:
-        form = TestRunFilterForm(request.user, instance=instance)
-
-    return render_to_response(
-        'dashboard_app/filter_add.html', {
-            'bread_crumb_trail': bread_crumb_trail,
-            'form': form,
-        }, RequestContext(request))
-
-
-@BreadCrumb("Add new filter", parent=filters_list)
-@login_required
-def filter_add(request):
-    return filter_form(
-        request,
-        BreadCrumbTrail.leading_to(filter_add))
-
-
-@BreadCrumb("Edit", parent=filter_detail, needs=['name', 'username'])
-def filter_edit(request, username, name):
-    if request.user.username != username:
-        raise PermissionDenied()
-    filter = TestRunFilter.objects.get(owner=request.user, name=name)
-    return filter_form(
-        request,
-        BreadCrumbTrail.leading_to(filter_edit, name=name, username=username),
-        instance=filter)
-
-
-@BreadCrumb("Delete", parent=filter_detail, needs=['name', 'username'])
-def filter_delete(request, username, name):
-    if request.user.username != username:
-        raise PermissionDenied()
-    filter = TestRunFilter.objects.get(owner=request.user, name=name)
-    if request.method == "POST":
-        if 'yes' in request.POST:
-            filter.delete()
-            return HttpResponseRedirect(reverse(filters_list))
-        else:
-            return HttpResponseRedirect(filter.get_absolute_url())
-    return render_to_response(
-        'dashboard_app/filter_delete.html', {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(filter_delete, name=name, username=username),
-            'filter': filter,
-        }, RequestContext(request))
-
-
-def filter_add_cases_for_test_json(request):
-    test = Test.objects.get(test_id=request.GET['test'])
-    result = TestCase.objects.filter(test=test).order_by('test_case_id').values('test_case_id', 'id')
-    return HttpResponse(
-        json.dumps(list(result)),
-        mimetype='application/json')
-
-
-def get_tests_json(request):
-
-    tests = Test.objects.filter(
-        test_runs__bundle__bundle_stream__testrunfilter__id=request.GET['id']).distinct()
-
-    data = serializers.serialize('json', tests)
-    return HttpResponse(data, mimetype='application/json')
-
-
-def get_test_cases_json(request):
-
-    test_cases = TestCase.objects.filter(
-        test__test_runs__bundle__bundle_stream__testrunfilter__id=request.GET['id']).distinct()
-
-    data = serializers.serialize('json', test_cases)
-    return HttpResponse(data, mimetype='application/json')
-
-
-def filter_attr_name_completion_json(request):
-    term = request.GET['term']
-    content_type_id = ContentType.objects.get_for_model(TestRun).id
-    result = NamedAttribute.objects.filter(
-        name__startswith=term, content_type_id=content_type_id
-        ).distinct().order_by('name').values_list('name', flat=True)
-    return HttpResponse(
-        json.dumps(list(result)),
-        mimetype='application/json')
-
-
-def filter_attr_value_completion_json(request):
-    name = request.GET['name']
-    term = request.GET['term']
-    content_type_id = ContentType.objects.get_for_model(TestRun).id
-    result = NamedAttribute.objects.filter(
-        name=name, content_type_id=content_type_id, value__startswith=term
-        ).distinct().order_by('value').values_list('value', flat=True)
-    return HttpResponse(
-        json.dumps(list(result)),
-        mimetype='application/json')
-
-
-def _iter_matching(seq1, seq2, key):
-    """Iterate over sequences in the order given by the key function, matching
-    elements with matching key values.
-
-    For example:
-
-    >>> seq1 = [(1, 2), (2, 3)]
-    >>> seq2 = [(1, 3), (3, 4)]
-    >>> def key(pair): return pair[0]
-    >>> list(_iter_matching(seq1, seq2, key))
-    [(1, (1, 2), (1, 3)), (2, (2, 3), None), (3, None, (3, 4))]
-    """
-    seq1.sort(key=key)
-    seq2.sort(key=key)
-    sentinel = object()
-    def next(it):
-        try:
-            o = it.next()
-            return (key(o), o)
-        except StopIteration:
-            return (sentinel, None)
-    iter1 = iter(seq1)
-    iter2 = iter(seq2)
-    k1, o1 = next(iter1)
-    k2, o2 = next(iter2)
-    while k1 is not sentinel or k2 is not sentinel:
-        if k1 is sentinel:
-            yield (k2, None, o2)
-            k2, o2 = next(iter2)
-        elif k2 is sentinel:
-            yield (k1, o1, None)
-            k1, o1 = next(iter1)
-        elif k1 == k2:
-            yield (k1, o1, o2)
-            k1, o1 = next(iter1)
-            k2, o2 = next(iter2)
-        elif k1 < k2:
-            yield (k1, o1, None)
-            k1, o1 = next(iter1)
-        else: # so k1 > k2...
-            yield (k2, None, o2)
-            k2, o2 = next(iter2)
-
-
-def _test_run_difference(test_run1, test_run2, cases=None):
-    test_results1 = list(test_run1.test_results.all().select_related('test_case'))
-    test_results2 = list(test_run2.test_results.all().select_related('test_case'))
-    def key(tr):
-        return tr.test_case.test_case_id
-    differences = []
-    for tc_id, tc1, tc2 in _iter_matching(test_results1, test_results2, key):
-        if cases is not None and tc_id not in cases:
-            continue
-        if tc1:
-            tc1 = tc1.result_code
-        if tc2:
-            tc2 = tc2.result_code
-        if tc1 != tc2:
-            differences.append({
-                'test_case_id': tc_id,
-                'first_result': tc1,
-                'second_result': tc2,
-                })
-    return differences
-
-
-def compare_filter_matches(user, filter_data, tag1, tag2):
-    matches = evaluate_filter(user, filter_data)
-    match1, match2 = matches.with_tags(tag1, tag2)
-    test_cases_for_test_id = {}
-    for test in filter_data['tests']:
-        test_cases = test['test_cases']
-        if test_cases:
-            test_cases = set([tc.test_case_id for tc in test_cases])
-        else:
-            test_cases = None
-        test_cases_for_test_id[test['test'].test_id] = test_cases
-    test_run_info = []
-    def key(tr):
-        return tr.test.test_id
-    for key, tr1, tr2 in _iter_matching(match1.test_runs, match2.test_runs, key):
-        if tr1 is None:
-            table = None
-            only = 'right'
-            tr = tr2
-            tag = tag2
-            cases = None
-        elif tr2 is None:
-            table = None
-            only = 'left'
-            tr = tr1
-            tag = tag1
-            cases = None
-        else:
-            only = None
-            tr = None
-            tag = None
-            cases = test_cases_for_test_id.get(key)
-            test_result_differences = _test_run_difference(tr1, tr2, cases)
-            if test_result_differences:
-                table = TestResultDifferenceTable(
-                    "test-result-difference-" + escape(key), data=test_result_differences)
-                table.base_columns['first_result'].verbose_name = mark_safe(
-                    '<a href="%s">build %s: %s</a>' % (
-                        tr1.get_absolute_url(), escape(tag1), escape(key)))
-                table.base_columns['second_result'].verbose_name = mark_safe(
-                    '<a href="%s">build %s: %s</a>' % (
-                        tr2.get_absolute_url(), escape(tag2), escape(key)))
-            else:
-                table = None
-            if cases:
-                cases = sorted(cases)
-                if len(cases) > 1:
-                    cases = ', '.join(cases[:-1]) + ' or ' + cases[-1]
-                else:
-                    cases = cases[0]
-        test_run_info.append(dict(
-            only=only,
-            key=key,
-            table=table,
-            tr=tr,
-            tag=tag,
-            cases=cases))
-    return test_run_info
-
-
-@BreadCrumb(
-    "Comparing builds {tag1} and {tag2}",
-    parent=filter_detail,
-    needs=['username', 'name', 'tag1', 'tag2'])
-def compare_matches(request, username, name, tag1, tag2):
-    filter = TestRunFilter.objects.get(owner__username=username, name=name)
-    if not filter.public and filter.owner != request.user:
-        raise PermissionDenied()
-    filter_data = filter.as_data()
-    test_run_info = compare_filter_matches(request.user, filter_data, tag1, tag2)
-    return render_to_response(
-        "dashboard_app/filter_compare_matches.html", {
-            'test_run_info': test_run_info,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                compare_matches,
-                name=name,
-                username=username,
-                tag1=tag1,
-                tag2=tag2),
-        }, RequestContext(request))

=== removed directory 'dashboard_app/views/image_reports'
=== removed file 'dashboard_app/views/image_reports/__init__.py'
--- dashboard_app/views/image_reports/__init__.py	2013-09-03 15:03:06 +0000
+++ dashboard_app/views/image_reports/__init__.py	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-# Copyright (C) 2010-2013 Linaro Limited
-#
-# Author: Stevan Radakovic <stevan.radakovic@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.

=== removed file 'dashboard_app/views/image_reports/forms.py'
--- dashboard_app/views/image_reports/forms.py	2013-09-13 12:59:23 +0000
+++ dashboard_app/views/image_reports/forms.py	1970-01-01 00:00:00 +0000
@@ -1,91 +0,0 @@
-# Copyright (C) 2010-2013 Linaro Limited
-#
-# Author: Stevan Radakovic <stevan.radakovic@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-from django import forms
-
-from dashboard_app.models import (
-    ImageReport,
-    ImageReportChart,
-    ImageChartFilter,
-    ImageChartTest,
-    ImageChartTestCase,
-    Test,
-    TestCase,
-)
-
-
-class ImageReportEditorForm(forms.ModelForm):
-    class Meta:
-        model = ImageReport
-        exclude = ('owner', 'is_published',)
-
-    def save(self, commit=True, **kwargs):
-        instance = super(ImageReportEditorForm,
-                         self).save(commit=commit, **kwargs)
-        return instance
-
-    def is_valid(self):
-        return super(ImageReportEditorForm, self).is_valid()
-
-    def full_clean(self):
-        super(ImageReportEditorForm, self).full_clean()
-
-    def __init__(self, user, *args, **kwargs):
-        super(ImageReportEditorForm, self).__init__(*args, **kwargs)
-
-
-class ImageReportChartForm(forms.ModelForm):
-    class Meta:
-        model = ImageReportChart
-        widgets = {'image_report': forms.HiddenInput}
-
-    def __init__(self, user, *args, **kwargs):
-        super(ImageReportChartForm, self).__init__(*args, **kwargs)
-        if len(self.instance.imagechartfilter_set.all()) != 0:
-            self.fields['chart_type'].label = ""
-            self.fields['chart_type'].widget = forms.HiddenInput()
-
-    def save(self, commit=True, **kwargs):
-        instance = super(ImageReportChartForm,
-                         self).save(commit=commit, **kwargs)
-        return instance
-
-
-class ImageChartFilterForm(forms.ModelForm):
-
-    image_chart_tests = forms.ModelMultipleChoiceField(
-        widget=forms.MultipleHiddenInput,
-        queryset=Test.objects.all().order_by("id"),
-        required=False)
-    image_chart_test_cases = forms.ModelMultipleChoiceField(
-        widget=forms.MultipleHiddenInput,
-        queryset=TestCase.objects.all().order_by("id"),
-        required=False)
-
-    class Meta:
-        model = ImageChartFilter
-        widgets = {'filter': forms.HiddenInput,
-                   'image_chart': forms.HiddenInput,}
-
-    def __init__(self, user, *args, **kwargs):
-        super(ImageChartFilterForm, self).__init__(*args, **kwargs)
-
-    def save(self, commit=True, **kwargs):
-        instance = super(ImageChartFilterForm,
-                         self).save(commit=commit, **kwargs)
-        return instance

=== removed file 'dashboard_app/views/image_reports/views.py'
--- dashboard_app/views/image_reports/views.py	2013-09-13 12:59:23 +0000
+++ dashboard_app/views/image_reports/views.py	1970-01-01 00:00:00 +0000
@@ -1,325 +0,0 @@
-# Copyright (C) 2010-2013 Linaro Limited
-#
-# Author: Stevan Radakovic <stevan.radakovic@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-import json
-
-from django.contrib.auth.decorators import login_required
-from django.core.exceptions import PermissionDenied, ValidationError
-from django.http import HttpResponse, HttpResponseRedirect
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-from django.utils.safestring import mark_safe
-
-from lava_server.bread_crumbs import (
-    BreadCrumb,
-    BreadCrumbTrail,
-)
-
-from dashboard_app.views import index
-
-from dashboard_app.views.image_reports.forms import (
-    ImageReportEditorForm,
-    ImageReportChartForm,
-    ImageChartFilterForm,
-    )
-
-from dashboard_app.models import (
-    ImageReport,
-    ImageReportChart,
-    ImageChartFilter,
-    ImageChartTest,
-    ImageChartTestCase,
-    Test,
-    TestCase,
-    TestRunFilter,
-    )
-
-from dashboard_app.views.filters.tables import AllFiltersSimpleTable
-
-
-
-@BreadCrumb("Image reports", parent=index)
-def image_report_list(request):
-
-    if request.user.is_authenticated():
-        image_reports = ImageReport.objects.all()
-    else:
-        image_reports = None
-
-    return render_to_response(
-        'dashboard_app/image_report_list.html', {
-            "image_reports": image_reports,
-        }, RequestContext(request)
-    )
-
-@BreadCrumb("Image report {name}", parent=image_report_list, needs=['name'])
-def image_report_detail(request, name):
-    image_report = ImageReport.objects.get(name=name)
-
-    return render_to_response(
-        'dashboard_app/image_report_detail.html', {
-            'image_report': image_report,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                image_report_detail, name=name),
-        }, RequestContext(request)
-    )
-
-@BreadCrumb("Add new image report", parent=image_report_list)
-@login_required
-def image_report_add(request):
-    return image_report_form(
-        request,
-        BreadCrumbTrail.leading_to(image_report_add))
-
-@BreadCrumb("Update image report {name}", parent=image_report_list,
-            needs=['name'])
-@login_required
-def image_report_edit(request, name):
-    image_report = ImageReport.objects.get(name=name)
-    return image_report_form(
-        request,
-        BreadCrumbTrail.leading_to(image_report_edit,
-                                   name=name),
-        instance=image_report)
-
-@BreadCrumb("Publish image report {name}", parent=image_report_list,
-            needs=['name'])
-@login_required
-def image_report_publish(request, name):
-    image_report = ImageReport.objects.get(name=name)
-    image_report.is_published = True
-    image_report.save()
-
-    return render_to_response(
-        'dashboard_app/image_report_detail.html', {
-            'image_report': image_report,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                image_report_detail, name=name),
-        }, RequestContext(request)
-    )
-
-@BreadCrumb("Unpublish image report {name}", parent=image_report_list,
-            needs=['name'])
-@login_required
-def image_report_unpublish(request, name):
-    image_report = ImageReport.objects.get(name=name)
-    image_report.is_published = False
-    image_report.save()
-
-    return render_to_response(
-        'dashboard_app/image_report_detail.html', {
-            'image_report': image_report,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                image_report_detail, name=name),
-        }, RequestContext(request)
-    )
-
-def image_report_form(request, bread_crumb_trail, instance=None):
-
-    if request.method == 'POST':
-
-        form = ImageReportEditorForm(request.user, request.POST,
-                                     instance=instance)
-        if form.is_valid():
-            image_report = form.save()
-            return HttpResponseRedirect(image_report.get_absolute_url())
-
-    else:
-        form = ImageReportEditorForm(request.user, instance=instance)
-
-    return render_to_response(
-        'dashboard_app/image_report_form.html', {
-            'bread_crumb_trail': bread_crumb_trail,
-            'form': form,
-        }, RequestContext(request))
-
-@BreadCrumb("Image chart details", parent=image_report_list)
-def image_chart_detail(request, id):
-    image_chart = ImageReportChart.objects.get(id=id)
-
-    return render_to_response(
-        'dashboard_app/image_report_chart_detail.html', {
-            'image_chart': image_chart,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                image_chart_detail, id=id),
-        }, RequestContext(request)
-    )
-
-@BreadCrumb("Add new image chart", parent=image_report_list)
-@login_required
-def image_chart_add(request):
-    return image_chart_form(
-        request,
-        BreadCrumbTrail.leading_to(image_chart_add))
-
-@BreadCrumb("Update image chart", parent=image_report_list)
-@login_required
-def image_chart_edit(request, id):
-    image_chart = ImageReportChart.objects.get(id=id)
-    return image_chart_form(
-        request,
-        BreadCrumbTrail.leading_to(image_chart_edit,
-                                   id=id),
-        instance=image_chart)
-
-def image_chart_form(request, bread_crumb_trail, instance=None):
-
-    if request.method == 'POST':
-
-        form = ImageReportChartForm(request.user, request.POST,
-                                    instance=instance)
-        if form.is_valid():
-            image_chart = form.save()
-            return HttpResponseRedirect(
-                image_chart.get_absolute_url())
-
-    else:
-        form = ImageReportChartForm(request.user, instance=instance)
-
-    if not instance:
-        image_report_id = request.GET.get('image_report_id', None)
-    else:
-        image_report_id = instance.image_report.id
-
-    filters_table = AllFiltersSimpleTable("all-filters", None)
-
-    return render_to_response(
-        'dashboard_app/image_report_chart_form.html', {
-            'bread_crumb_trail': bread_crumb_trail,
-            'form': form,
-            'filters_table': filters_table,
-            'image_report_id': image_report_id,
-        }, RequestContext(request))
-
-@BreadCrumb("Image chart add filter", parent=image_report_list)
-def image_chart_filter_add(request, id):
-    image_chart = ImageReportChart.objects.get(id=id)
-    return image_chart_filter_form(
-        request,
-        BreadCrumbTrail.leading_to(image_chart_filter_add),
-        chart_instance=image_chart)
-
-@BreadCrumb("Update image chart filter", parent=image_report_list)
-@login_required
-def image_chart_filter_edit(request, id):
-    image_chart_filter = ImageChartFilter.objects.get(id=id)
-    return image_chart_filter_form(
-        request,
-        BreadCrumbTrail.leading_to(image_chart_filter_edit, id=id),
-        instance=image_chart_filter)
-
-@BreadCrumb("Image chart add filter", parent=image_report_list)
-def image_chart_filter_delete(request, id):
-    image_chart_filter = ImageChartFilter.objects.get(id=id)
-    url = image_chart_filter.image_chart.get_absolute_url()
-    image_chart_filter.delete()
-    return HttpResponseRedirect(url)
-
-def image_chart_filter_form(request, bread_crumb_trail, chart_instance=None,
-                            instance=None):
-
-    if instance:
-        chart_instance = instance.image_chart
-
-    if request.method == 'POST':
-
-        form = ImageChartFilterForm(request.user, request.POST,
-                                    instance=instance)
-
-        if form.is_valid():
-
-            chart_filter = form.save()
-            aliases = request.POST.getlist('aliases')
-
-
-            if chart_filter.image_chart.chart_type == 'pass/fail':
-
-                image_chart_tests = Test.objects.filter(
-                    imagecharttest__image_chart_filter=chart_filter).order_by(
-                        'id')
-
-                tests = form.cleaned_data['image_chart_tests']
-
-                for index, test in enumerate(tests):
-                    if test in image_chart_tests:
-                        chart_test = ImageChartTest.objects.get(
-                            image_chart_filter=chart_filter, test=test)
-                        chart_test.name = aliases[index]
-                        chart_test.save()
-                    else:
-                        chart_test = ImageChartTest()
-                        chart_test.image_chart_filter = chart_filter
-                        chart_test.test = test
-                        chart_test.name = aliases[index]
-                        chart_test.save()
-
-                for index, chart_test in enumerate(image_chart_tests):
-                    if chart_test not in tests:
-                        ImageChartTest.objects.get(
-                            image_chart_filter=chart_filter,
-                            test=chart_test).delete()
-
-                return HttpResponseRedirect(
-                    chart_filter.image_chart.get_absolute_url())
-
-            else:
-
-                image_chart_test_cases = TestCase.objects.filter(
-                    imagecharttestcase__image_chart_filter=
-                    chart_filter).order_by('id')
-
-                test_cases = form.cleaned_data['image_chart_test_cases']
-
-                for index, test_case in enumerate(test_cases):
-                    if test_case in image_chart_test_cases:
-                        chart_test_case = ImageChartTestCase.objects.get(
-                            image_chart_filter=chart_filter,
-                            test_case=test_case)
-                        chart_test_case.name = aliases[index]
-                        chart_test_case.save()
-                    else:
-                        chart_test_case = ImageChartTestCase()
-                        chart_test_case.image_chart_filter = chart_filter
-                        chart_test_case.test_case = test_case
-                        chart_test_case.name = aliases[index]
-                        chart_test_case.save()
-
-                for index, chart_test_case in enumerate(
-                        image_chart_test_cases):
-                    if chart_test_case not in test_cases:
-                        ImageChartTestCase.objects.get(
-                            image_chart_filter=chart_filter,
-                            test_case=chart_test_case).delete()
-
-                return HttpResponseRedirect(
-                    chart_filter.image_chart.get_absolute_url())
-
-    else:
-        form = ImageChartFilterForm(request.user, instance=instance,
-                                    initial={'image_chart': chart_instance})
-
-    filters_table = AllFiltersSimpleTable("all-filters", None)
-
-    return render_to_response(
-        'dashboard_app/image_chart_filter_form.html', {
-            'bread_crumb_trail': bread_crumb_trail,
-            'filters_table': filters_table,
-            'image_chart': chart_instance,
-            'instance': instance,
-            'form': form,
-        }, RequestContext(request))

=== removed file 'dashboard_app/views/images.py'
--- dashboard_app/views/images.py	2013-07-03 11:42:45 +0000
+++ dashboard_app/views/images.py	1970-01-01 00:00:00 +0000
@@ -1,164 +0,0 @@
-# Copyright (C) 2010-2012 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from django.http import HttpResponseRedirect
-from django.shortcuts import get_object_or_404, render_to_response
-from django.template import RequestContext
-from django.views.decorators.http import require_POST
-
-from lava_server.bread_crumbs import (
-    BreadCrumb,
-    BreadCrumbTrail,
-)
-
-from dashboard_app.filters import evaluate_filter
-from dashboard_app.models import (
-    LaunchpadBug,
-    Image,
-    ImageSet,
-    TestRun,
-)
-from dashboard_app.views import index
-import json
-
-@BreadCrumb("Image Reports", parent=index)
-def image_report_list(request):
-    imagesets = ImageSet.objects.filter()
-    imagesets_data = []
-    for imageset in imagesets:
-        images_data = []
-        for image in imageset.images.all():
-            # Migration hack: Image.filter cannot be auto populated, so ignore
-            # images that have not been migrated to filters for now.
-            if image.filter:
-                filter_data = image.filter.as_data()
-                image_data = {
-                    'name': image.name,
-                    'bundle_count': evaluate_filter(request.user, filter_data).count(),
-                    'link': image.name,
-                    }
-                images_data.append(image_data)
-        images_data.sort(key=lambda d:d['name'])
-        imageset_data = {
-            'name': imageset.name,
-            'images': images_data,
-            }
-        imagesets_data.append(imageset_data)
-    imagesets_data.sort(key=lambda d:d['name'])
-    return render_to_response(
-        "dashboard_app/image-reports.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(image_report_list),
-            'imagesets': imagesets_data,
-        }, RequestContext(request))
-
-
-@BreadCrumb("{name}", parent=image_report_list, needs=['name'])
-def image_report_detail(request, name):
-
-    image = Image.objects.get(name=name)
-    filter_data = image.filter.as_data()
-    matches = evaluate_filter(request.user, filter_data, prefetch_related=['launchpad_bugs', 'test_results'])[:50]
-
-    build_number_to_cols = {}
-
-    test_run_names = set()
-
-    for match in matches:
-        for test_run in match.test_runs:
-            name = test_run.test.test_id
-            denorm = test_run.denormalization
-            if denorm.count_fail == 0:
-                cls = 'present pass'
-            else:
-                    cls = 'present fail'
-            bug_ids = sorted([b.bug_id for b in test_run.launchpad_bugs.all()])
-
-            measurements = [{'measurement': str(item.measurement)}
-                            for item in test_run.test_results.all()]
-
-            test_run_data = dict(
-                present=True,
-                cls=cls,
-                uuid=test_run.analyzer_assigned_uuid,
-                passes=denorm.count_pass,
-                total=denorm.count_pass + denorm.count_fail,
-                link=test_run.get_permalink(),
-                bug_ids=bug_ids,
-                measurements=measurements,                
-                )
-            if (match.tag, test_run.bundle.uploaded_on) not in build_number_to_cols:
-                build_number_to_cols[(match.tag, test_run.bundle.uploaded_on)] = {
-                    'test_runs': {},
-                    'number': str(match.tag),
-                    'date': str(test_run.bundle.uploaded_on),
-                    'link': test_run.bundle.get_absolute_url(),
-                    }
-            build_number_to_cols[(match.tag, test_run.bundle.uploaded_on)]['test_runs'][name] = test_run_data
-            if name != 'lava':
-                test_run_names.add(name)
-
-
-    test_run_names = sorted(test_run_names)
-    test_run_names.insert(0, 'lava')
-
-    cols = [c for n, c in sorted(build_number_to_cols.items())]
-
-    table_data = {}
-
-    for test_run_name in test_run_names:
-        row_data = []
-        for col in cols:
-            test_run_data = col['test_runs'].get(test_run_name)
-            if not test_run_data:
-                test_run_data = dict(
-                    present=False,
-                    cls='missing',
-                    )
-            row_data.append(test_run_data)
-        table_data[test_run_name] = row_data
-
-    return render_to_response(
-        "dashboard_app/image-report.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                image_report_detail, name=image.name),
-            'image': image,
-            'chart_data': json.dumps(table_data),
-            'test_names': json.dumps(test_run_names),
-            'columns': json.dumps(cols),
-        }, RequestContext(request))
-
-
-@require_POST
-def link_bug_to_testrun(request):
-    testrun = get_object_or_404(TestRun, analyzer_assigned_uuid=request.POST['uuid'])
-    bug_id = request.POST['bug']
-    lpbug = LaunchpadBug.objects.get_or_create(bug_id=int(bug_id))[0]
-    testrun.launchpad_bugs.add(lpbug)
-    testrun.save()
-    return HttpResponseRedirect(request.POST['back'])
-
-
-@require_POST
-def unlink_bug_and_testrun(request):
-    testrun = get_object_or_404(TestRun, analyzer_assigned_uuid=request.POST['uuid'])
-    bug_id = request.POST['bug']
-    lpbug = LaunchpadBug.objects.get_or_create(bug_id=int(bug_id))[0]
-    testrun.launchpad_bugs.remove(lpbug)
-    testrun.save()
-    return HttpResponseRedirect(request.POST['back'])

=== removed file 'dashboard_app/views/pmqa.py'
--- dashboard_app/views/pmqa.py	2013-01-11 02:26:37 +0000
+++ dashboard_app/views/pmqa.py	1970-01-01 00:00:00 +0000
@@ -1,203 +0,0 @@
-# Copyright (C) 2010-2012 Linaro Limited
-#
-# Author: Michael Hudson-Doyle <michael.hudson@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-
-from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
-from django.shortcuts import render_to_response
-from django.template import RequestContext
-
-from lava_server.bread_crumbs import (
-    BreadCrumb,
-    BreadCrumbTrail,
-)
-
-from dashboard_app.filters import evaluate_filter
-from dashboard_app.models import (
-    BundleStream,
-    PMQABundleStream,
-    Test,
-)
-from dashboard_app.views import index
-from dashboard_app.views.filters.tables import (
-    FilterTable,
-    )
-from dashboard_app.views.filters.views import (
-    compare_filter_matches,
-    )
-
-
-@BreadCrumb("PM QA view", parent=index)
-@login_required
-def pmqa_view(request):
-    test = Test.objects.get(test_id='pwrmgmt')
-    device_types_with_results = []
-    prefix__device_type_result = {}
-
-    from lava_scheduler_app.models import DeviceType
-    device_types = list(DeviceType.objects.filter(display=True).values_list('name', flat=True))
-    bundle_streams = [pmqabs.bundle_stream for pmqabs in PMQABundleStream.objects.all()]
-    bundle_streams.sort(key=lambda bs:bs.pathname)
-
-    for bs in bundle_streams:
-        c = len(device_types_with_results)
-        for device_type in device_types:
-            if device_type.startswith('rtsm'):
-                continue
-            filter_data = {
-                'bundle_streams': [bs],
-                'attributes': [('target.device_type', device_type)],
-                'tests': [{'test':test, 'test_cases':[]}],
-                'build_number_attribute': 'build.id',
-                }
-            matches = list(evaluate_filter(request.user, filter_data)[:50])
-            if matches:
-                match = matches[0]
-                m0 = match.serializable(include_links=False)
-                del m0['tag']
-                last_difference = None
-                for m in matches[1:]:
-                    m1 = m.serializable(include_links=False)
-                    del m1['tag']
-                    if m1 != m0:
-                        last_difference = (
-                            m.tag,
-                            reverse(compare_pmqa_results,
-                                    kwargs={
-                                        'pathname': bs.pathname,
-                                        'device_type': device_type,
-                                        'build1': str(m.tag),
-                                        'build2': str(match.tag),
-                                        }))
-                        break
-                tr = match.test_runs[0]
-                device_types_with_results.append({
-                    'sn': bs.slug,
-                    'device_type': device_type,
-                    'date': tr.bundle.uploaded_on,
-                    'build': match.tag,
-                    'link': tr.get_absolute_url(),
-                    'width': 0,
-                    'last_difference': last_difference,
-                    'filter_link': reverse(pmqa_filter_view, kwargs=dict(
-                        pathname=bs.pathname, device_type=device_type)),
-                    })
-                for result in tr.test_results.all().select_related('test_case'):
-                    prefix = result.test_case.test_case_id.split('.')[0]
-                    device_type__result = prefix__device_type_result.setdefault(prefix, {})
-                    d = device_type__result.setdefault(device_type, {'pass': 0, 'total': 0, 'present':True})
-                    if result.result == result.RESULT_PASS:
-                        d['pass'] += 1
-                    d['total'] += 1
-            if len(device_types_with_results) > c:
-                device_types_with_results[c]['width'] = len(device_types_with_results) - c
-    results = []
-    prefixes = sorted(prefix__device_type_result)
-    for prefix in prefixes:
-        board_results = []
-        for d in device_types_with_results:
-            cell_data = prefix__device_type_result[prefix].get(d['device_type'])
-            if cell_data is not None:
-                if cell_data['total'] == cell_data['pass']:
-                    cell_data['css_class'] = 'pass'
-                else:
-                    cell_data['css_class'] = 'fail'
-            else:
-                cell_data = {
-                    'css_class': 'missing',
-                    'present': False,
-                    }
-            board_results.append(cell_data)
-        results.append((prefix, board_results))
-    return render_to_response(
-        "dashboard_app/pmqa-view.html", {
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(pmqa_view),
-            'device_types_with_results': device_types_with_results,
-            'results': results,
-        }, RequestContext(request))
-
-
-def pmqa_filter_view_json(request, pathname, device_type):
-    test = Test.objects.get(test_id='pwrmgmt')
-    bs = BundleStream.objects.get(pathname=pathname)
-    filter_data = {
-        'bundle_streams': [bs],
-        'attributes': [('target.device_type', device_type)],
-        'tests': [{'test':test, 'test_cases':[]}],
-        'build_number_attribute': 'build.id',
-        }
-    return FilterTable.json(request, params=(request.user, filter_data))
-
-
-@BreadCrumb(
-    "PMQA results for {pathname} on {device_type}",
-    parent=pmqa_view,
-    needs=['pathname', 'device_type'])
-def pmqa_filter_view(request, pathname, device_type):
-    test = Test.objects.get(test_id='pwrmgmt')
-    bs = BundleStream.objects.get(pathname=pathname)
-    filter_data = {
-        'bundle_streams': [bs],
-        'attributes': [('target.device_type', device_type)],
-        'tests': [{'test':test, 'test_cases':[]}],
-        'build_number_attribute': 'build.id',
-        }
-    return render_to_response(
-        "dashboard_app/pmqa_filter.html", {
-            'filter_table': FilterTable(
-                "filter-table",
-                reverse(
-                    pmqa_filter_view_json,
-                    kwargs=dict(
-                        pathname=pathname,
-                        device_type=device_type)),
-                params=(request.user, filter_data)),
-            'bundle_stream': bs.slug,
-            'device_type': device_type,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                pmqa_filter_view,
-                pathname=pathname,
-                device_type=device_type),
-        }, RequestContext(request))
-
-
-@BreadCrumb(
-    "Comparing builds {build1} and {build2}",
-    parent=pmqa_filter_view,
-    needs=['pathname', 'device_type', 'build1', 'build2'])
-def compare_pmqa_results(request, pathname, device_type, build1, build2):
-    test = Test.objects.get(test_id='pwrmgmt')
-    bs = BundleStream.objects.get(pathname=pathname)
-    filter_data = {
-        'bundle_streams': [bs],
-        'attributes': [('target.device_type', device_type)],
-        'tests': [{'test':test, 'test_cases':[]}],
-        'build_number_attribute': 'build.id',
-        }
-    test_run_info = compare_filter_matches(request.user, filter_data, build1, build2)
-    return render_to_response(
-        "dashboard_app/filter_compare_matches.html", {
-            'test_run_info': test_run_info,
-            'bread_crumb_trail': BreadCrumbTrail.leading_to(
-                compare_pmqa_results,
-                pathname=pathname,
-                device_type=device_type,
-                build1=build1,
-                build2=build2),
-        }, RequestContext(request))
-

=== removed file 'dashboard_app/xmlrpc.py'
--- dashboard_app/xmlrpc.py	2013-08-23 10:31:07 +0000
+++ dashboard_app/xmlrpc.py	1970-01-01 00:00:00 +0000
@@ -1,1114 +0,0 @@
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of LAVA Dashboard
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-"""
-XMP-RPC API
-"""
-
-import datetime
-import decimal
-import logging
-import re
-import xmlrpclib
-import hashlib
-import json
-import os
-from django.contrib.auth.models import User, Group
-from django.core.urlresolvers import reverse
-from django.db import IntegrityError, DatabaseError
-from linaro_django_xmlrpc.models import (
-    ExposedAPI,
-    Mapper,
-    xml_rpc_signature,
-)
-
-from dashboard_app import __version__
-from dashboard_app.filters import evaluate_filter
-from dashboard_app.models import (
-    Bundle,
-    BundleStream,
-    DataView,
-    Test,
-    TestRunFilter,
-    TestDefinition,
-)
-
-
-class errors:
-    """
-    A namespace for error codes that may be returned by various XML-RPC
-    methods. Where applicable existing status codes from HTTP protocol
-    are reused
-    """
-    AUTH_FAILED = 100
-    AUTH_BLOCKED = 101
-    BAD_REQUEST = 400
-    AUTH_REQUIRED = 401
-    FORBIDDEN = 403
-    NOT_FOUND = 404
-    CONFLICT = 409
-    INTERNAL_SERVER_ERROR = 500
-    NOT_IMPLEMENTED = 501
-
-
-class DashboardAPI(ExposedAPI):
-    """
-    Dashboard API object.
-
-    All public methods are automatically exposed as XML-RPC methods
-    """
-
-    data_view_connection = DataView.get_connection()
-
-    @xml_rpc_signature('str')
-    def version(self):
-        """
-        Name
-        ----
-        `version` ()
-
-        Description
-        -----------
-        Return dashboard server version. The version is a string with
-        dots separating five components.
-
-        The components are:
-            1. major version
-            2. minor version
-            3. micro version
-            4. release level
-            5. serial
-
-        See: http://docs.python.org/library/sys.html#sys.version_info
-
-        Return value
-        -------------
-        Server version string
-        """
-        return ".".join(map(str, __version__))
-
-    def _put(self, content, content_filename, pathname):
-        try:
-            logging.debug("Getting bundle stream")
-            bundle_stream = BundleStream.objects.accessible_by_principal(self.user).get(pathname=pathname)
-        except BundleStream.DoesNotExist:
-            logging.debug("Bundle stream does not exist, aborting")
-            raise xmlrpclib.Fault(errors.NOT_FOUND,
-                                  "Bundle stream not found")
-        if not bundle_stream.can_upload(self.user):
-            raise xmlrpclib.Fault(
-                errors.FORBIDDEN, "You cannot upload to this stream")
-        try:
-            logging.debug("Creating bundle object")
-            bundle = Bundle.objects.create_with_content(bundle_stream, self.user, content_filename, content)
-        except (IntegrityError, ValueError) as exc:
-            logging.debug("Raising xmlrpclib.Fault(errors.CONFLICT)")
-            raise xmlrpclib.Fault(errors.CONFLICT, str(exc))
-        except:
-            logging.exception("big oops")
-            raise
-        else:
-            logging.debug("Deserializing bundle")
-            bundle.deserialize()
-            return bundle
-
-    @xml_rpc_signature('str', 'str', 'str', 'str')
-    def put(self, content, content_filename, pathname):
-        """
-        Name
-        ----
-        `put` (`content`, `content_filename`, `pathname`)
-
-        Description
-        -----------
-        Upload a bundle to the server.
-
-        Arguments
-        ---------
-        `content`: string
-            Full text of the bundle. This *SHOULD* be a valid JSON
-            document and it *SHOULD* match the "Dashboard Bundle Format
-            1.0" schema. The SHA1 of the content *MUST* be unique or a
-            ``Fault(409, "...")`` is raised. This is used to protect
-            from simple duplicate submissions.
-        `content_filename`: string
-            Name of the file that contained the text of the bundle. The
-            `content_filename` can be an arbitrary string and will be
-            stored along with the content for reference.
-        `pathname`: string
-            Pathname of the bundle stream where a new bundle should
-            be created and stored. This argument *MUST* designate a
-            pre-existing bundle stream or a ``Fault(404, "...")`` exception
-            is raised. In addition the user *MUST* have access
-            permission to upload bundles there or a ``Fault(403, "...")``
-            exception is raised. See below for access rules.
-
-        Return value
-        ------------
-        If all goes well this function returns the SHA1 of the content.
-
-        Exceptions raised
-        -----------------
-        404
-            Either:
-
-                - Bundle stream not found
-                - Uploading to specified stream is not permitted
-        409
-            Duplicate bundle content
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream upload access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-
-        """
-        bundle = self._put(content, content_filename, pathname)
-        logging.debug("Returning bundle SHA1")
-        return bundle.content_sha1
-
-    @xml_rpc_signature('str', 'str', 'str', 'str')
-    def put_ex(self, content, content_filename, pathname):
-        """
-        Name
-        ----
-        `put` (`content`, `content_filename`, `pathname`)
-
-        Description
-        -----------
-        Upload a bundle to the server.  A variant on put_ex that returns the
-        URL of the bundle instead of its SHA1.
-
-        Arguments
-        ---------
-        `content`: string
-            Full text of the bundle. This *SHOULD* be a valid JSON
-            document and it *SHOULD* match the "Dashboard Bundle Format
-            1.0" schema. The SHA1 of the content *MUST* be unique or a
-            ``Fault(409, "...")`` is raised. This is used to protect
-            from simple duplicate submissions.
-        `content_filename`: string
-            Name of the file that contained the text of the bundle. The
-            `content_filename` can be an arbitrary string and will be
-            stored along with the content for reference.
-        `pathname`: string
-            Pathname of the bundle stream where a new bundle should
-            be created and stored. This argument *MUST* designate a
-            pre-existing bundle stream or a ``Fault(404, "...")`` exception
-            is raised. In addition the user *MUST* have access
-            permission to upload bundles there or a ``Fault(403, "...")``
-            exception is raised. See below for access rules.
-
-        Return value
-        ------------
-        If all goes well this function returns the full URL of the bundle.
-
-        Exceptions raised
-        -----------------
-        404
-            Either:
-
-                - Bundle stream not found
-                - Uploading to specified stream is not permitted
-        409
-            Duplicate bundle content
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream upload access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-
-        """
-        bundle = self._put(content, content_filename, pathname)
-        logging.debug("Returning permalink to bundle")
-        return self._context.request.build_absolute_uri(
-            reverse(
-                'dashboard_app.views.redirect_to_bundle',
-                kwargs={'content_sha1':bundle.content_sha1}))
-
-    def put_pending(self, content, pathname, group_name):
-        """
-        Name
-        ----
-        `put_pending` (`content`, `pathname`, `group_name`)
-
-        Description
-        -----------
-        MultiNode internal call.
-
-        Stores the bundle until the coordinator allows the complete
-        bundle list to be aggregated from the list and submitted by put_group
-
-        Arguments
-        ---------
-        `content`: string
-            Full text of the bundle. This *MUST* be a valid JSON
-            document and it *SHOULD* match the "Dashboard Bundle Format
-            1.0" schema. The SHA1 of the content *MUST* be unique or a
-            ``Fault(409, "...")`` is raised. This is used to protect
-            from simple duplicate submissions.
-        `pathname`: string
-            Pathname of the bundle stream where a new bundle should
-            be created and stored. This argument *MUST* designate a
-            pre-existing bundle stream or a ``Fault(404, "...")`` exception
-            is raised. In addition the user *MUST* have access
-            permission to upload bundles there or a ``Fault(403, "...")``
-            exception is raised. See below for access rules.
-        `group_name`: string
-            Unique ID of the MultiNode group. Other pending bundles will
-            be aggregated into a single result bundle for this group.
-
-        Return value
-        ------------
-        If all goes well this function returns the SHA1 of the content.
-
-        Exceptions raised
-        -----------------
-        404
-            Either:
-
-                - Bundle stream not found
-                - Uploading to specified stream is not permitted
-        409
-            Duplicate bundle content
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream upload access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-
-        """
-        try:
-            logging.debug("Getting bundle stream")
-            bundle_stream = BundleStream.objects.accessible_by_principal(self.user).get(pathname=pathname)
-        except BundleStream.DoesNotExist:
-            logging.debug("Bundle stream does not exist, aborting")
-            raise xmlrpclib.Fault(errors.NOT_FOUND,
-                                  "Bundle stream not found")
-        if not bundle_stream.can_upload(self.user):
-            raise xmlrpclib.Fault(
-                errors.FORBIDDEN, "You cannot upload to this stream")
-        try:
-            # add this to a list which put_group can use.
-            sha1 = hashlib.sha1()
-            sha1.update(content)
-            hexdigest = sha1.hexdigest()
-            groupfile = "/tmp/%s" % group_name
-            with open(groupfile, "a+") as grp_file:
-                grp_file.write("%s\n" % content)
-            return hexdigest
-        except Exception as e:
-            logging.debug("Dashboard pending submission caused an exception: %s" % e)
-
-    def put_group(self, content, content_filename, pathname, group_name):
-        """
-        Name
-        ----
-        `put_group` (`content`, `content_filename`, `pathname`, `group_name`)
-
-        Description
-        -----------
-        MultiNode internal call.
-
-        Adds the final bundle to the list, aggregates the list
-        into a single group bundle and submits the group bundle.
-
-        Arguments
-        ---------
-        `content`: string
-            Full text of the bundle. This *MUST* be a valid JSON
-            document and it *SHOULD* match the "Dashboard Bundle Format
-            1.0" schema. The SHA1 of the content *MUST* be unique or a
-            ``Fault(409, "...")`` is raised. This is used to protect
-            from simple duplicate submissions.
-        `content_filename`: string
-            Name of the file that contained the text of the bundle. The
-            `content_filename` can be an arbitrary string and will be
-            stored along with the content for reference.
-        `pathname`: string
-            Pathname of the bundle stream where a new bundle should
-            be created and stored. This argument *MUST* designate a
-            pre-existing bundle stream or a ``Fault(404, "...")`` exception
-            is raised. In addition the user *MUST* have access
-            permission to upload bundles there or a ``Fault(403, "...")``
-            exception is raised. See below for access rules.
-        `group_name`: string
-            Unique ID of the MultiNode group. Other pending bundles will
-            be aggregated into a single result bundle for this group. At
-            least one other bundle must have already been submitted as
-            pending for the specified MultiNode group. LAVA Coordinator
-            causes the parent job to wait until all nodes have been marked
-            as having pending bundles, even if some bundles are empty.
-
-        Return value
-        ------------
-        If all goes well this function returns the full URL of the bundle.
-
-        Exceptions raised
-        -----------------
-        ValueError:
-            One or more bundles could not be converted to JSON prior
-            to aggregation.
-        404
-            Either:
-
-                - Bundle stream not found
-                - Uploading to specified stream is not permitted
-        409
-            Duplicate bundle content
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream upload access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-
-        """
-        grp_file = "/tmp/%s" % group_name
-        bundle_set = {}
-        bundle_set[group_name] = []
-        if os.path.isfile(grp_file):
-            with open(grp_file, "r") as grp_data:
-                grp_list = grp_data.readlines()
-            for testrun in grp_list:
-                bundle_set[group_name].append(json.loads(testrun))
-        # Note: now that we have the data from the group, the group data file could be re-used
-        # as an error log which is simpler than debugging through XMLRPC.
-        else:
-            raise ValueError("Aggregation failure for %s - check coordinator rpc_delay?" % group_name)
-        group_tests = []
-        try:
-            json_data = json.loads(content)
-        except ValueError:
-            logging.debug("Invalid JSON content within the sub_id zero bundle")
-            json_data = None
-        try:
-            bundle_set[group_name].append(json_data)
-        except Exception as e:
-            logging.debug("appending JSON caused exception %s" % e)
-        try:
-            for bundle_list in bundle_set[group_name]:
-                for test_run in bundle_list['test_runs']:
-                    group_tests.append(test_run)
-        except Exception as e:
-            logging.debug("aggregating bundles caused exception %s" % e)
-        group_content = json.dumps({"test_runs": group_tests, "format": json_data['format']})
-        bundle = self._put(group_content, content_filename, pathname)
-        logging.debug("Returning permalink to aggregated bundle for %s" % group_name)
-        permalink = self._context.request.build_absolute_uri(
-            reverse('dashboard_app.views.redirect_to_bundle',
-                    kwargs={'content_sha1': bundle.content_sha1}))
-        # only delete the group file when things go well.
-        if os.path.isfile(grp_file):
-            os.remove(grp_file)
-        return permalink
-
-    def get(self, content_sha1):
-        """
-        Name
-        ----
-        `get` (`content_sha1`)
-
-        Description
-        -----------
-        Download a bundle from the server.
-
-        Arguments
-        ---------
-        `content_sha1`: string
-            SHA1 hash of the content of the bundle to download. This
-            *MUST* designate an bundle or ``Fault(404, "...")`` is raised.
-
-        Return value
-        ------------
-        This function returns an XML-RPC struct with the following fields:
-
-        `content_filename`: string
-            The value that was stored on a previous call to put()
-        `content`: string
-            The full text of the bundle
-
-        Exceptions raised
-        -----------------
-        - 404 Bundle not found
-        - 403 Permission denied
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream download access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-        """
-        try:
-            bundle = Bundle.objects.get(content_sha1=content_sha1)
-            if not bundle.bundle_stream.is_accessible_by(self.user):
-                raise xmlrpclib.Fault(
-                    403, "Permission denied.  User does not have permissions "
-                    "to access this bundle.")
-        except Bundle.DoesNotExist:
-            raise xmlrpclib.Fault(errors.NOT_FOUND,
-                    "Bundle not found")
-        else:
-            return {"content": bundle.content.read(),
-                    "content_filename": bundle.content_filename}
-
-    @xml_rpc_signature('struct')
-    def streams(self):
-        """
-        Name
-        ----
-        `streams` ()
-
-        Description
-        -----------
-        List all bundle streams that the user has access to
-
-        Arguments
-        ---------
-        None
-
-        Return value
-        ------------
-        This function returns an XML-RPC array of XML-RPC structs with
-        the following fields:
-
-        `pathname`: string
-            The pathname of the bundle stream
-        `name`: string
-            The user-configurable name of the bundle stream
-        `user`: string
-            The username of the owner of the bundle stream for personal
-            streams or an empty string for public and team streams.
-        `group`: string
-            The name of the team that owsn the bundle stream for team
-            streams or an empty string for public and personal streams.
-        `bundle_count`: int
-            Number of bundles that are in this stream
-
-        Exceptions raised
-        -----------------
-        None
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream download access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-        """
-        bundle_streams = BundleStream.objects.accessible_by_principal(self.user)
-        return [{
-            'pathname': bundle_stream.pathname,
-            'name': bundle_stream.name,
-            'user': bundle_stream.user.username if bundle_stream.user else "",
-            'group': bundle_stream.group.name if bundle_stream.group else "",
-            'bundle_count': bundle_stream.bundles.count(),
-            } for bundle_stream in bundle_streams]
-
-    def bundles(self, pathname):
-        """
-        Name
-        ----
-        `bundles` (`pathname`)
-
-        Description
-        -----------
-        List all bundles in a specified bundle stream
-
-        Arguments
-        ---------
-        `pathname`: string
-            The pathname of the bundle stream to query. This argument
-            *MUST* designate an existing stream or Fault(404, "...") is
-            raised. The user *MUST* have access to this stream or
-            Fault(403, "...") is raised.
-
-        Return value
-        ------------
-        This function returns an XML-RPC array of XML-RPC structs with
-        the following fields:
-
-        `uploaded_by`: string
-            The username of the user that uploaded this bundle or
-            empty string if this bundle was uploaded anonymously.
-        `uploaded_on`: datetime
-            The timestamp when the bundle was uploaded
-        `content_filename`: string
-            The filename of the original bundle file
-        `content_sha1`: string
-            The SHA1 hash if the content of the bundle
-        `content_size`: int
-            This element was added in server version 0.4
-            The size of the content
-        `is_deserialized`: bool
-            True if the bundle was de-serialized successfully, false otherwise
-
-
-        Exceptions raised
-        -----------------
-        404
-            Either:
-
-                - Bundle stream not found
-                - Listing bundles in this bundle stream is not permitted
-
-        Rules for bundle stream access
-        ------------------------------
-        The following rules govern bundle stream download access rights:
-            - all anonymous streams are accessible
-            - personal streams are accessible to owners
-            - team streams are accessible to team members
-        """
-        try:
-            bundle_stream = BundleStream.objects.accessible_by_principal(self.user).get(pathname=pathname)
-        except BundleStream.DoesNotExist:
-            raise xmlrpclib.Fault(errors.NOT_FOUND, "Bundle stream not found")
-        return [{
-            'uploaded_by': bundle.uploaded_by.username if bundle.uploaded_by else "",
-            'uploaded_on': bundle.uploaded_on,
-            'content_filename': bundle.content_filename,
-            'content_sha1': bundle.content_sha1,
-            'content_size': bundle.content.size,
-            'is_deserialized': bundle.is_deserialized
-            } for bundle in bundle_stream.bundles.all().order_by("uploaded_on")]
-
-    @xml_rpc_signature('str')
-    def get_test_names(self, device_type=None):
-        """
-        Name
-        ----
-        `get_test_names` ([`device_type`]])
-
-        Description
-        -----------
-        Get the name of all the tests that have run on a particular device type.
-
-        Arguments
-        ---------
-        `device_type`: string
-            The type of device the retrieved test names should apply to.
-
-        Return value
-        ------------
-        This function returns an XML-RPC array of test names.
-        """
-        test_names = []
-        if device_type:
-            for test in Test.objects.filter(
-                test_runs__attributes__name='target.device_type',
-                test_runs__attributes__value=device_type).distinct():
-                test_names.append(test.test_id)
-        else:
-            for test in Test.objects.all():
-                test_names.append(test.test_id)
-        return test_names
-
-    def deserialize(self, content_sha1):
-        """
-        Name
-        ----
-        `deserialize` (`content_sha1`)
-
-        Description
-        -----------
-        Deserialize bundle on the server
-
-        Arguments
-        ---------
-        `content_sha1`: string
-            SHA1 hash of the content of the bundle to download. This
-            *MUST* designate an bundle or ``Fault(404, "...")`` is raised.
-
-        Return value
-        ------------
-        True - deserialization okay
-        False - deserialization not needed
-
-        Exceptions raised
-        -----------------
-        404
-            Bundle not found
-        409
-            Bundle import failed
-        """
-        try:
-            bundle = Bundle.objects.get(content_sha1=content_sha1)
-        except Bundle.DoesNotExist:
-            raise xmlrpclib.Fault(errors.NOT_FOUND, "Bundle not found")
-        if bundle.is_deserialized:
-            return False
-        bundle.deserialize()
-        if bundle.is_deserialized is False:
-            raise xmlrpclib.Fault(
-                errors.CONFLICT,
-                bundle.deserialization_error.error_message)
-        return True
-
-    def make_stream(self, pathname, name):
-        """
-        Name
-        ----
-        `make_stream` (`pathname`, `name`)
-
-        Description
-        -----------
-        Create a bundle stream with the specified pathname
-
-        Arguments
-        ---------
-        `pathname`: string
-            The pathname must refer to an anonymous stream
-        `name`: string
-            The name of the stream (free form description text)
-
-        Return value
-        ------------
-        pathname is returned
-
-        Exceptions raised
-        -----------------
-        403
-            Pathname does not designate an anonymous stream
-        409
-            Bundle stream with the specified pathname already exists
-
-        Available Since
-        ---------------
-        0.3
-        """
-        # Work around bug https://bugs.launchpad.net/lava-dashboard/+bug/771182
-        # Older clients would send None as the name and this would trigger an
-        # IntegrityError to be raised by BundleStream.objects.create() below
-        # which in turn would be captured by the fault handler and reported as
-        # an unrelated issue to the user. Let's work around that by using an
-        # empty string instead.
-        if name is None:
-            name = ""
-        try:
-            user_name, group_name, slug, is_public, is_anonymous = BundleStream.parse_pathname(pathname)
-        except ValueError as ex:
-            raise xmlrpclib.Fault(errors.FORBIDDEN, str(ex))
-
-        # Start with those to simplify the logic below
-        user = None
-        group = None
-        if is_anonymous is False:
-            if self.user is not None:
-                assert is_anonymous is False
-                assert self.user is not None
-                if user_name is not None:
-                    if user_name != self.user.username:
-                        raise xmlrpclib.Fault(
-                            errors.FORBIDDEN,
-                            "Only user {user!r} could create this stream".format(user=user_name))
-                    user = self.user  # map to real user object
-                elif group_name is not None:
-                    try:
-                        group = self.user.groups.get(name=group_name)
-                    except Group.DoesNotExist:
-                        raise xmlrpclib.Fault(
-                            errors.FORBIDDEN,
-                            "Only a member of group {group!r} could create this stream".format(group=group_name))
-            else:
-                assert is_anonymous is False
-                assert self.user is None
-                raise xmlrpclib.Fault(
-                    errors.FORBIDDEN, "Only anonymous streams can be constructed (you are not signed in)")
-        else:
-            assert is_anonymous is True
-            assert user_name is None
-            assert group_name is None
-            # Hacky but will suffice for now
-            user = User.objects.get_or_create(username="anonymous-owner")[0]
-        try:
-            bundle_stream = BundleStream.objects.create(
-                user=user,
-                group=group,
-                slug=slug,
-                is_public=is_public,
-                is_anonymous=is_anonymous,
-                name=name)
-        except IntegrityError:
-            raise xmlrpclib.Fault(
-                errors.CONFLICT,
-                "Stream with the specified pathname already exists")
-        else:
-            return bundle_stream.pathname
-
-    def data_views(self):
-        """
-        Name
-        ----
-        `data_views` ()
-
-        Description
-        -----------
-        List all data views
-
-        Arguments
-        ---------
-        None
-
-        Return value
-        ------------
-        This function returns an XML-RPC array of XML-RPC structs with
-        the following fields:
-
-        `name`: string
-            Data view name declared in the definition file
-        `summary`: string
-            One-line description string suitable for developers
-
-        Exceptions raised
-        -----------------
-        None
-        """
-        return [{
-            'name': data_view.name,
-            'summary': data_view.summary,
-            "documentation": data_view.documentation,
-            "arguments": [{
-                "name": arg.name,
-                "type": arg.type,
-                "help": arg.help,
-                "default": arg.default
-            } for arg in data_view.arguments]
-        } for data_view in DataView.repository.all()]
-
-    def data_view_info(self, name):
-        """
-        Name
-        ----
-        `data_view_info` (`name`)
-
-        Description
-        -----------
-        Describe a specific data view. This function looks up data view by name and returns rich information. See below for details
-
-        Arguments
-        ---------
-        `name`: string
-            Name of the data view to lookup
-
-
-        Return value
-        ------------
-        This function returns an XML-RPC struct with the following fields:
-
-        `name`: string
-            Data view name declared in the definition file
-        `summary`: string
-            One-line description string suitable for developers
-        `documentation`: string
-            Longer documentation that described the purpose and indented usage of this data view
-        `sql`: string or null
-            The SQL of query specific to the currently running database (the
-            actual query that is executed by query-data-view. Since some data
-            views use database specific SQL the query may not be available.
-        `argments` an XML-RPC array of XML-RPC structs with the following fields:
-            `name`: Argument name
-            `type`: Argument type, one of "number", "string" or "boolean"
-            `help`: Help string for this argument
-            `default`: Default value of an argument (or null if not available)
-
-
-        Exceptions raised
-        -----------------
-        404
-            Name does not designate a data view
-        """
-        try:
-            data_view = DataView.repository.get(name=name)
-        except DataView.DoesNotExist:
-            raise xmlrpclib.Fault(errors.NOT_FOUND, "Data view not found")
-        else:
-            query = data_view.get_backend_specific_query(self.data_view_connection)
-            return {
-                "name": data_view.name,
-                "summary": data_view.summary,
-                "documentation": data_view.documentation,
-                "sql": query.sql_template if query is not None else None,
-                "arguments": [{
-                    "name": arg.name,
-                    "type": arg.type,
-                    "help": arg.help,
-                    "default": arg.default
-                } for arg in data_view.arguments]
-            }
-
-    def query_data_view(self, name, arguments):
-        """
-        Name
-        ----
-        `query_data_view` (name, arguments)
-
-        Description
-        -----------
-        List all data views
-
-        Arguments
-        ---------
-        None
-
-        Return value
-        ------------
-        This function returns an XML-RPC struct with the following fields:
-
-        `rows`: XML-RPC array of XML-RPC arrays
-            Each item corresponds to cell in a row
-        `columns`: XML-RPC array of XML-RPC structs with the following fields:
-            `name`: XML-RPC string - name of the column
-            `type`: XML-RPC string - column type (future extension, currently unused)
-
-        Exceptions raised
-        -----------------
-        TBD
-        """
-        try:
-            data_view = DataView.repository.get(name=name)
-        except DataView.DoesNotExist:
-            raise xmlrpclib.Fault(errors.NOT_FOUND, "Data view not found")
-        try:
-            rows, columns = data_view(self.data_view_connection, **arguments)
-        except (LookupError, TypeError, ValueError, DatabaseError) as exc:
-            raise xmlrpclib.Fault(errors.INTERNAL_SERVER_ERROR, str(exc))
-        else:
-            rows = [[float(cell) if isinstance(cell, decimal.Decimal) else cell for cell in row] for row in rows]
-            return {
-                "rows": rows,
-                "columns": [{
-                    "name": item[0],
-                    "type": item[1]
-                } for item in columns]
-            }
-
-    def _get_filter_data(self, filter_name):
-        match = re.match("~([-_A-Za-z0-9]+)/([-_A-Za-z0-9]+)", filter_name)
-        if not match:
-            raise xmlrpclib.Fault(errors.BAD_REQUEST, "filter_name must be of form ~owner/filter-name")
-        owner_name, filter_name = match.groups()
-        try:
-            owner = User.objects.get(username=owner_name)
-        except User.NotFound:
-            raise xmlrpclib.Fault(errors.NOT_FOUND, "user %s not found" % owner_name)
-        try:
-            filter = TestRunFilter.objects.get(owner=owner, name=filter_name)
-        except TestRunFilter.NotFound:
-            raise xmlrpclib.Fault(errors.NOT_FOUND, "filter %s not found" % filter_name)
-        if not filter.public and self.user != owner:
-            if self.user:
-                raise xmlrpclib.Fault(
-                    errors.FORBIDDEN, "forbidden")
-            else:
-                raise xmlrpclib.Fault(
-                    errors.AUTH_REQUIRED, "authentication required")
-        return filter.as_data()
-
-    def get_filter_results(self, filter_name, count=10, offset=0):
-        """
-        Name
-        ----
-         ::
-
-          get_filter_results(filter_name, count=10, offset=0)
-
-        Description
-        -----------
-
-        Return information about the test runs and results that a given filter
-        matches.
-
-        Arguments
-        ---------
-
-        ``filter_name``:
-           The name of a filter in the format ~owner/name.
-        ``count``:
-           The maximum number of matches to return.
-        ``offset``:
-           Skip over this many results.
-
-        Return value
-        ------------
-
-        A list of "filter matches".  A filter match describes the results of
-        matching a filter against one or more test runs::
-
-          {
-            'tag': either a stringified date (bundle__uploaded_on) or a build number
-            'test_runs': [{
-                'test_id': test_id
-                'link': link-to-test-run,
-                'passes': int, 'fails': int, 'skips': int, 'total': int,
-                # only present if filter specifies cases for this test:
-                'specific_results': [{
-                    'test_case_id': test_case_id,
-                    'link': link-to-test-result,
-                    'result': pass/fail/skip/unknown,
-                    'measurement': string-containing-decimal-or-None,
-                    'units': units,
-                    }],
-                }]
-            # Only present if filter does not specify tests:
-            'pass_count': int,
-            'fail_count': int,
-          }
-
-        """
-        filter_data = self._get_filter_data(filter_name)
-        matches = evaluate_filter(self.user, filter_data, descending=False)
-        matches = matches[offset:offset+count]
-        return [match.serializable() for match in matches]
-
-    def get_filter_results_since(self, filter_name, since=None):
-        """
-        Name
-        ----
-         ::
-
-          get_filter_results_since(filter_name, since=None)
-
-        Description
-        -----------
-
-        Return information about the test runs and results that a given filter
-        matches that are more recent than a previous match -- in more detail,
-        results where the ``tag`` is greater than the value passed in
-        ``since``.
-
-        The idea of this method is that it will be called from a cron job to
-        update previously accessed results.  Something like this::
-
-           previous_results = json.load(open('results.json'))
-           results = previous_results + server.dashboard.get_filter_results_since(
-              filter_name, previous_results[-1]['tag'])
-           ... do things with results ...
-           json.save(results, open('results.json', 'w'))
-
-        If called without passing ``since`` (or with ``since`` set to
-        ``None``), this method returns up to 100 matches from the filter.  In
-        fact, the matches are always capped at 100 -- so set your cronjob to
-        execute frequently enough that there are less than 100 matches
-        generated between calls!
-
-        Arguments
-        ---------
-
-        ``filter_name``:
-           The name of a filter in the format ~owner/name.
-        ``since``:
-           The 'tag' of the most recent result that was retrieved from this
-           filter.
-
-        Return value
-        ------------
-
-        A list of "filter matches".  A filter match describes the results of
-        matching a filter against one or more test runs::
-
-          {
-            'tag': either a stringified date (bundle__uploaded_on) or a build number
-            'test_runs': [{
-                'test_id': test_id
-                'link': link-to-test-run,
-                'passes': int, 'fails': int, 'skips': int, 'total': int,
-                # only present if filter specifies cases for this test:
-                'specific_results': [{
-                    'test_case_id': test_case_id,
-                    'link': link-to-test-result,
-                    'result': pass/fail/skip/unknown,
-                    'measurement': string-containing-decimal-or-None,
-                    'units': units,
-                    }],
-                }]
-            # Only present if filter does not specify tests:
-            'pass_count': int,
-            'fail_count': int,
-          }
-
-        """
-        filter_data = self._get_filter_data(filter_name)
-        matches = evaluate_filter(self.user, filter_data, descending=False)
-        if since is not None:
-            if filter_data.get('build_number_attribute') is not None:
-                try:
-                    since = datetime.datetime.strptime(since, "%Y-%m-%d %H:%M:%S.%f")
-                except ValueError:
-                    raise xmlrpclib.Fault(
-                        errors.BAD_REQUEST, "cannot parse since argument as datetime")
-            matches = matches.since(since)
-        matches = matches[:100]
-        return [match.serializable() for match in matches]
-
-    @xml_rpc_signature('str')
-    def get_test_definitions(self, os=None, device=None, environment=None):
-        """
-        Name
-        ----
-        `get_test_definitions` ([`os`[, `device`[, `environment`]]])
-
-        Description
-        -----------
-        Get the name and url of all the test definitions.
-
-        Arguments
-        ---------
-        `os`: string
-            The type of operating system the retrieved test definitions should
-            apply to.
-
-        `device`: string
-            The type of device the retrieved test definitions should apply to.
-
-        `environment`: string
-            The type of test environment the retrieved test definitions should
-            apply to.
-
-        Return value
-        ------------
-        This function returns an XML-RPC structure of test definition name and
-        URL where the test definition exists.
-        """
-        testdefs = {}
-        tds = TestDefinition.objects.all()
-
-        if os:
-            tds = tds.filter(target_os__contains=os)
-
-        if device:
-            tds = tds.filter(target_dev_types__contains=device)
-
-        if environment:
-            tds = tds.filter(environment__contains=environment)
-
-        for testdef in tds:
-                testdefs[testdef.name] = testdef.url
-        return testdefs
-
-# Mapper used by the legacy URL
-legacy_mapper = Mapper()
-legacy_mapper.register_introspection_methods()
-legacy_mapper.register(DashboardAPI, '')

=== removed directory 'doc'
=== removed file 'doc/changes.rst'
--- doc/changes.rst	2013-01-15 21:40:20 +0000
+++ doc/changes.rst	1970-01-01 00:00:00 +0000
@@ -1,270 +0,0 @@
-Version History
-***************
-
-.. _version_0_29:
-
-Version 0.29
-============
-* Removed some useless and incomplete functionality
-* Added a powermgmt view
-* Added abiltiy to compare filter matches
-* Fix regression in bundle notifications on filters
-
-.. _version_0_28:
-
-Version 0.28
-============
-* added Filter's API via XMLRPC
-
-.. _version_0_27:
-
-Version 0.27
-============
-* say "pass" rather than "Test passed" etc in a few places
-
-.. _version_0_26:
-
-Version 0.26
-============
-* redo UI related to test results and attachments
-
-.. _version_0_25_2:
-
-Version 0.25.2
-==============
-* Add the filter subscription mail template to the sdist.
-
-.. _version_0_25_1:
-
-Version 0.25.1
-==============
-* Add some log messages around sending filter subscription mail.
-* Fix a bug with subscribing to filters that do not specify any tests.
-
-.. _version_0_25:
-
-Version 0.25
-============
-* UI fixes to our filter views
-
-.. _version_0_24:
-
-Version 0.24
-============
-* Improved user experience when not logged in
-* Support 1.4 and 1.5 bundle formats
-
-.. _version_0_23_1:
-
-Version 0.23.1
-==============
-* Fix filter form media loading.
-
-.. _version_0_23:
-
-Version 0.23
-============
-* Added XML-RPC call to retrieve test names.
-* A better way of basing image reports on filters.
-* Somewhat split up the sprawling views.py.
-
-.. _version_0_22_1:
-
-Version 0.22.1
-==============
-* Urgent release week hacks to base image reports on filters.
-
-.. _version_0_22:
-
-Version 0.22
-============
-* Add the ability to group and order filter matches by a build number.
-* Allow filters to match multiple tests and test cases.
-
-.. _version_0_21:
-
-Version 0.21
-============
-* Add the concept of a test run filter.
-
-.. _version_0_20:
-
-Version 0.20
-============
-
-* make the bundle page robust against the bundle not existing on disk
-* ensure table row heights match up in image status view
-* few fixes for image status views
-* import bundle cleanup
-
-.. _version_0_19:
-
-Version 0.19
-============
-* Add image status views and models for use by the QA services team.
-* Allow linking test runs to launchpad bugs from the image status view.
-
-.. _version_0_18:
-
-Version 0.18
-============
-
-* Add link to job details for bundles
-
-.. _version_0_17:
-
-Version 0.17
-============
-
-* Fix sorting by column on the test runs in bundle view.
-* Display passes & fails in the test run view of a bundle.
-
-.. _version_0_16:
-
-Version 0.16
-============
-
-* Make test_result.message respect newlines (bug #850633, Chris
-  Johnston)
-* Allow viewing images in bundles (bug #877984)
-
-.. _version_0_15:
-
-Version 0.15
-============
-
-* Remove the image status view.
-
-.. _version_0_14:
-
-Version 0.14
-============
-
-* Convert some tables to use AJAX pagination.
-* Add an admin function to support deleting an entire bundle, including
-  referenced test runs and results
-
-.. _version_0_13:
-
-Version 0.13
-============
-
-* Add :meth:`dashboard_app.BundleStream.can_upload()` that checks if user can
-  upload bundles to a specific stream.
-* Fix bug that allowed unauthorised users to upload data to any bundle stream
-  they could see https://bugs.launchpad.net/lava-dashboard/+bug/955669
-
-.. _version_0_12:
-
-Version 0.12
-============
-
-* Remove outdated installation documentation and replace it with basic
-  instructions for using pip or direct source code (Thanks to Adam Konarski)
-* Built documentation will now include TODO markers (Thanks to Adam Kornacki)
-* Add a link to the launchpad FAQ to the documentation
-* Fix test suite failing due to fixtures being out of date.
-
-.. _version_0_11:
-
-Version 0.11
-============
-
-.. _version_0_10_1:
-
-Version 0.10.1
-==============
-
-*  Fix sorting on bundle_list
-
-.. _version_0_10:
-
-Version 0.10.0
-==============
-
-*  Fix breadcrumb + titlebar system after moving this responsibilty to lava-server
-*  do not limit the lengths of strings in attribute keys and values
-
-.. _version_0_9_3:
-
-Version 0.9.3
-=============
-
-* Some minor improvements to the bundle list template
-
-.. _version_0_9_2:
-
-Version 0.9.2
-=============
-*  Require latest lava-server
-*  Make all lava-dashboard views associated with lava-server index breadcrumb
-*  Remove the context processor, use front page data feeder and start using application menu
-*  Merge fix for database migration dependencies
-
-.. _version_0_9_1:
-
-Version 0.9.1
-=============
-
-*  Merge for bug LP:#877859: add measurement information to the json output.
-   This change is used by the Android build service.
-
-.. _version_0_6:
-
-Version 0.6
-===========
-
-This version was released as 2011.07 in the Linaro monthly release process.
-
-Release highlights:
-
-* New UI synchronized with lava-server, the UI is going to be changed in the
-  next release to be more in line with the official Linaro theme. Currently
-  most changes are under-the-hood, sporting more jQuery UI CSS.
-* New test browser that allows to see all the registered tests and their test
-  cases.
-* New data view browser, similar to data view browser.
-* New permalink system that allows easy linking to bundles, test runs and test results.
-* New image status views that allow for quick inspection of interesting
-  hardware pack + root filesystem combinations.
-* New image status detail view with color-coded information about test failures
-  affecting current and historic instances of a particular root filesystem +
-  hardware pack combination.
-* New image test history view showing all the runs of a particular test on a
-  particular combination of root filesystem + hardware pack.
-* New table widget for better table display with support for client side
-  sorting and searching.
-* New option to render data reports without any navigation that is suitable for
-  embedding inside an iframe (by appending &iframe=yes to the URL)
-* New view for showing text attachments associated with test runs.
-* New view showing test runs associated with a specific bundle.
-* New view showing the raw JSON text of a bundle.
-* New view for inspecting bundle deserialization failures.
-* Integration with lava-server/RPC2/ for web APIs
-* Added support for non-anonymous submissions (test results uploaded by
-  authenticated users), including uploading results to personal (owned by
-  person), team (owned by group), public (visible) and private (hidden from
-  non-owners) bundle streams.
-* Added support for creating non-anonymous bundle streams with
-  dashboard.make_stream() (for authenticated users)
-
-.. _version_0_5:
-
-Version 0.5
-===========
-
-This version was released as 2011.06 in the Linaro monthly release process.
-
-Release highlights:
-
-* The dashboard has been split into two components, a generic host for server
-  side applications (now called the lava-server) and a test result repository
-  and browser (now called the lava-dashboard).
-* A big dependency revamp has made it possible to install the dashboard (as
-  lava-dashboard) straight from the python package index (pypi.python.org).
-  This simplifies deployment in certain environments.
-* There is now a :ref:`installation` manual that describes how to deploy the
-  dashboard from a PPA.
-* It is now possible to browse and discover available data views directly form
-  the web interface. This makes it easier to create additional reports.
-

=== removed file 'doc/conf.py'
--- doc/conf.py	2012-01-24 20:00:06 +0000
+++ doc/conf.py	1970-01-01 00:00:00 +0000
@@ -1,204 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# LAVA Dashboard documentation build configuration file, created by
-# sphinx-quickstart on Mon Dec 27 16:39:47 2010.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys
-import os
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-sys.path.append(os.path.abspath('..'))
-
-# -- General configuration -----------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.coverage']
-
-# Configuration for sphinx.ext.todo
-todo_include_todos = True
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = []
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Lava Dashboard'
-copyright = u'2010-2011, Linaro Limited'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-import versiontools
-import dashboard_app
-version = "%d.%d" % dashboard_app.__version__[0:2]
-# The full version, including alpha/beta/rc tags.
-release = versiontools.format_version(dashboard_app.__version__)
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directory, that shouldn't be searched
-# for source files.
-exclude_trees = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  Major themes that come with
-# Sphinx are currently 'default' and 'sphinxdoc'.
-html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = []
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_use_modindex = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'VersionToolsDocumentation'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'LavaDashboard.tex', u'Lava Dashboard Documentation',
-   u'Zygmunt Krynicki', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_use_modindex = True
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'http://docs.python.org/': None}

=== removed file 'doc/faq.rst'
--- doc/faq.rst	2012-01-28 17:53:53 +0000
+++ doc/faq.rst	1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-FAQ
-***
-
-If you have any questions concerning lava-dashboard, you may find answers 
-here: https://answers.launchpad.net/lava-dashboard. 
-If you still need help, feel free to ask.

=== removed file 'doc/index.rst'
--- doc/index.rst	2012-03-15 03:02:46 +0000
+++ doc/index.rst	1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
-============================
-Lava Dashboard Documentation
-============================
-
-.. automodule:: dashboard_app 
-
-.. seealso:: To get started quickly see :ref:`usage`
-.. seealso:: See what's new in :ref:`version_0_13`
-
-Features
-========
-
-
-
-Indices and tables
-==================
-
-.. toctree::
-    :maxdepth: 2
-    
-    installation.rst
-    usage.rst
-    changes.rst
-    reference.rst
-    faq.rst
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-

=== removed file 'doc/installation.rst'
--- doc/installation.rst	2013-09-11 15:53:29 +0000
+++ doc/installation.rst	1970-01-01 00:00:00 +0000
@@ -1,76 +0,0 @@
-.. _installation:
-
-Installation
-^^^^^^^^^^^^
-
-To install LAVA Dashboard, you will first need to install LAVA Server.
-For more information about LAVA Server, see 
-`the Documentation </static/docs/>`_ on any LAVA instance.
-
-Using virtualenv
-****************
-
-Python Virtualenv is a useful tool for creating a sandbox for working
-with python modules.  In Ubuntu, you can get it by installing
-*python-virtualenv* using apt-get.  For source and pypi installations of
-non-production systems, it is highly recommended.
-
-Example usage ::
-
- $ virtualenv sandbox
- $ cd sandbox
- $ . bin/activate
-
-Once activated, the environment for that session will be set up so that
-subsequent commands will use the virtual environment settings.
-
-Installation from source
-************************
-
-This is the most complicated and error prone installation method. It requires
-the user to download source release tarballs. Unpack them and install them in
-the correct order. Depending on the exact set of components that are installed
-(especially client or server side components) some additional steps are
-necessary. This may include setting up the web application host (one of many
-possible configurations here), setting up the database (again multiple possible
-options, our recommendation is to use the latest stable version of PostgreSQL).
-
-For installing from source, it's normally much simpler to install from
-pypi first, then update using the source.  This is useful if you want
-to use it for development against your own branch. For instance, after 
-installing from pypi (see directions below) you could do the following.
-
-Updating in a virtualenv using source ::
-
- $ bzr branch lp:lava-dashboard
- $ cd lava-dashboard
- $ ./setup develop
-
-Installation from PypI
-**********************
-
-PyPi is the python package index (http://pypi.python.org/pypi). It is
-maintained by the python community and is the preferred distribution method
-used by many open source projects written in the python programming language.
-
-Here a front-end program, such as pip (http://pypi.python.org/pypi/pip) is used
-to install packages, and their python dependencies. Pip finds the required set
-of packages, downloads their source releases and does the hard work of figuring
-out the right way to put them together.
-
-This is the best compromise between wide system support (any flavour of Linux,
-OS X and Windows), simplicity, upgrade and availability. The downside is that
-it does not handle, by itself, the last mile. This method does not handle
-things like setting up and running the application server. It also requires the
-user to have additional development packages, such as python header files,
-database server header files, the C compiler and more.
-
-To install using pypi (For development only, not for production)::
-
- $ pip install lava-dashboard
- $ lava-server manage --development syncdb
- $ lava-server manage --development migrate
-
-You will need to answer a few questions during the syncdb step. This
-will use a simple sqlite database, and should normally only be used for
-testing or hacking on LAVA.

=== removed file 'doc/reference.rst'
--- doc/reference.rst	2011-06-28 11:42:54 +0000
+++ doc/reference.rst	1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-.. _code_reference:
-
-Rereference
-^^^^^^^^^^^
-
-TODO

=== removed file 'doc/usage.rst'
--- doc/usage.rst	2011-06-28 11:42:54 +0000
+++ doc/usage.rst	1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
-.. _usage:
-
-Usage
-*****
-
-TODO

=== removed directory 'examples'
=== removed directory 'examples/bundles'
=== removed file 'examples/bundles/attachment.json'
--- examples/bundles/attachment.json	2011-01-04 17:57:35 +0000
+++ examples/bundles/attachment.json	1970-01-01 00:00:00 +0000
@@ -1,46 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "result": "pass",
-          "test_case_id": "test-case-with-attachment",
-          "log_filename": "test-run1.log",
-          "log_lineno": 5,
-          "message": "Message from log that is still available"
-        }, 
-        {
-          "result": "pass",
-          "test_case_id": "test-case-without-attachment",
-          "log_filename": "test-run2.log",
-          "log_lineno": 2,
-          "message": "Message from log that is not longer available"
-        }, 
-        {
-          "result": "pass",
-          "test_case_id": "test-case-without-source",
-          "message": "Message from some other source"
-        }
-      ], 
-      "analyzer_assigned_date": "2011-01-04T15:29:46Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000006",
-      "test_id": "examples.attachments",
-      "attachments": {
-        "test-run1.log": [
-          "line 1\n",
-          "line 2\n",
-          "line 3\n",
-          "line 4\n",
-          "line 5\n",
-          "line 6\n",
-          "line 7\n",
-          "line 8\n",
-          "line 9\n",
-          "line 10\n"
-        ]
-      }
-    }
-  ], 
-  "format": "Dashboard Bundle Format 1.0"
-}

=== removed file 'examples/bundles/big.json'
--- examples/bundles/big.json	2010-12-21 13:11:39 +0000
+++ examples/bundles/big.json	1970-01-01 00:00:00 +0000
@@ -1,313 +0,0 @@
-{
-    "test_runs": [
-        {
-            "test_results": [
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }, 
-                {
-                    "result": "pass"
-                }
-            ], 
-            "analyzer_assigned_date": "2010-12-21T14:06:27Z", 
-            "time_check_performed": false, 
-            "test_id": "big-test", 
-            "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000004"
-        }
-    ], 
-    "format": "Dashboard Bundle Format 1.0"
-}

=== removed file 'examples/bundles/broken.json'
--- examples/bundles/broken.json	2010-12-20 09:45:31 +0000
+++ examples/bundles/broken.json	1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
-{
-  "format": "Dashboard Bundle Format -1.0"
-}

=== removed file 'examples/bundles/example_coremark.json'
--- examples/bundles/example_coremark.json	2011-03-18 12:27:39 +0000
+++ examples/bundles/example_coremark.json	1970-01-01 00:00:00 +0000
@@ -1,48 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "test_case_id": "total-ticks",
-          "result": "unknown",
-          "measurement": 15370,
-          "units": "ticks",
-          "log_filename": "toolchain/gcc-linaro-4.5-2010.10-0/logs/armv7l-maverick-cbuild11-pavo4/coremark-run.txt",
-          "log_lineno": 6
-        },
-        {
-          "test_case_id": "total-time",
-          "result": "unknown",
-          "measurement": 15.37,
-          "units": "seconds",
-          "log_filename": "toolchain/gcc-linaro-4.5-2010.10-0/logs/armv7l-maverick-cbuild11-pavo4/coremark-run.txt",
-          "log_lineno": 7
-        },
-        {
-          "test_case_id": "iterations-per-second",
-          "result": "unknown",
-          "measurement": 1301.236174,
-          "units": "iterations/second",
-          "log_filename": "toolchain/gcc-linaro-4.5-2010.10-0/logs/armv7l-maverick-cbuild11-pavo4/coremark-run.txt",
-          "log_lineno": 8
-        }
-      ],
-      "analyzer_assigned_date": "2011-03-18T12:48:22Z",
-      "time_check_performed": true,
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-00000000000B",
-      "test_id": "examples.coremark",
-      "attachments": [
-        {
-            "pathname": "toolchain/gcc-linaro-4.5-2010.10-0/logs/armv7l-maverick-cbuild11-pavo4/coremark-run.txt",
-            "mime_type": "text/plain",
-            "public_url": "http://builds.linaro.org/toolchain/gcc-linaro-4.5-2010.10-0/logs/armv7l-maverick-cbuild11-pavo4/coremark-run.txt"
-        }
-      ],
-      "attributes": {
-          "iterations": "20000",
-          "coremark size": "666"
-      }
-    }
-  ],
-  "format": "Dashboard Bundle Format 1.2"
-}

=== removed file 'examples/bundles/one-run.json'
--- examples/bundles/one-run.json	2010-12-20 09:45:31 +0000
+++ examples/bundles/one-run.json	1970-01-01 00:00:00 +0000
@@ -1,35 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "test_case_id": "helix-0", 
-          "result": "pass"
-        }, 
-        {
-          "test_case_id": "helix-1", 
-          "result": "fail"
-        }, 
-        {
-          "test_case_id": "helix-2", 
-          "result": "skip"
-        }, 
-        {
-          "test_case_id": "helix-3", 
-          "result": "unknown"
-        }, 
-        {
-          "test_case_id": "helix-4", 
-          "result": "unknown",
-          "measurement": 512.0,
-          "units": "bits/s"
-        } 
-      ], 
-      "analyzer_assigned_date": "2010-10-15T22:04:46Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000001",
-      "test_id": "double-helix"
-    }
-  ], 
-  "format": "Dashboard Bundle Format 1.0"
-}

=== removed file 'examples/bundles/source-refs.json'
--- examples/bundles/source-refs.json	2011-03-02 12:43:22 +0000
+++ examples/bundles/source-refs.json	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "result": "unknown"
-        }
-      ],
-      "analyzer_assigned_date": "2011-01-10T16:52:46Z",
-      "time_check_performed": false,
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-00000000000A",
-      "test_id": "source-refs",
-      "software_context": {
-        "sources": [
-          {
-            "branch_revision": 93556,
-            "branch_url": "lp:gcc-linaro/4.4",
-            "branch_vcs": "bzr",
-            "commit_timestamp": "2010-09-07T14:49:43Z",
-            "project_name": "linaro-gcc"
-          }
-        ]
-      }
-    }
-  ],
-  "format": "Dashboard Bundle Format 1.1"
-}

=== removed directory 'examples/bundles/templates'
=== removed file 'examples/bundles/templates/dummy.json'
--- examples/bundles/templates/dummy.json	2011-01-04 17:57:35 +0000
+++ examples/bundles/templates/dummy.json	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-{
-    "test_runs": [
-        {
-            "test_results": [
-                {
-                    "result": "pass"
-                }
-            ], 
-            "analyzer_assigned_date": "2010-12-21T14:06:27Z", 
-            "time_check_performed": false, 
-            "test_id": "clone-test", 
-            "analyzer_assigned_uuid": "00000000-0000-0000-@TEMPLATE@-000000000001"
-        }
-    ], 
-    "format": "Dashboard Bundle Format 1.0"
-}

=== removed file 'examples/bundles/test_result_detail.json'
--- examples/bundles/test_result_detail.json	2011-01-04 17:57:35 +0000
+++ examples/bundles/test_result_detail.json	1970-01-01 00:00:00 +0000
@@ -1,80 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "test_case_id": "test-case-0", 
-          "result": "pass",
-          "message": "Test result Message scrubbed from the log file",
-          "timestamp": "2010-09-17T16:34:21Z",
-          "log_filename": "testoutput.log",
-          "log_lineno": 1,
-          "duration" : "1d 1s 1us",
-           "attributes": {
-                          "attr1": "value1",
-                          "attr2": "value2"
-                         }
-        }, 
-        {
-          "test_case_id": "test-case-1", 
-          "result": "fail",
-          "message": "Test result Message scrubbed from the log file",
-          "timestamp": "2010-09-18T16:34:21Z",
-          "log_filename": "testoutput.log",
-          "log_lineno": 2,  
-          "duration" : "1d 1s 1us",
-           "attributes": {
-                          "attr1": "value1",
-                          "attr2": "value2"
-                         }
-        }, 
-        {
-          "test_case_id": "test-case-2", 
-          "result": "skip",
-          "message": "Test result Message scrubbed from the log file",
-          "timestamp": "2010-09-19T16:34:21Z",
-          "log_filename": "testoutput.log",
-          "log_lineno": 3,  
-          "duration" : "1d 1s 1us",
-           "attributes": {
-                          "attr1": "value1",
-                          "attr2": "value2"
-                         }
-        }, 
-        {
-          "test_case_id": "test-case-3", 
-          "result": "unknown",
-          "message": "Test result Message scrubbed from the log file",
-          "timestamp": "2010-09-20T16:34:21Z",
-          "log_filename": "testoutput.log",
-          "log_lineno": 4,  
-          "duration" : "1d 1s 1us",
-           "attributes": {
-                          "attr1": "value1",
-                          "attr2": "value2"
-                         }
-        }, 
-        {
-          "test_case_id": "test-case-4", 
-          "result": "unknown",
-          "measurement": 512.0,
-          "units": "bits/s",
-          "message": "Test result Message scrubbed from the log file",
-          "timestamp": "2010-09-21T16:34:21Z",
-          "log_filename": "testoutput.log",
-          "log_lineno": 5,  
-          "duration" : "1d 1s 1us",
-           "attributes": {
-                          "attr1": "value1",
-                          "attr2": "value2"
-                         }
-        } 
-      ], 
-      "analyzer_assigned_date": "2010-10-15T22:05:45Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000005",
-      "test_id": "detailed-test-results"
-    }
-  ], 
-  "format": "Dashboard Bundle Format 1.0"
-}

=== removed file 'examples/bundles/two-runs.json'
--- examples/bundles/two-runs.json	2010-12-20 09:45:31 +0000
+++ examples/bundles/two-runs.json	1970-01-01 00:00:00 +0000
@@ -1,65 +0,0 @@
-{
-  "test_runs": [
-    {
-      "test_results": [
-        {
-          "test_case_id": "helix-0", 
-          "result": "pass"
-        }, 
-        {
-          "test_case_id": "helix-1", 
-          "result": "fail"
-        }, 
-        {
-          "test_case_id": "helix-2", 
-          "result": "skip"
-        }, 
-        {
-          "test_case_id": "helix-3", 
-          "result": "unknown"
-        }, 
-        {
-          "test_case_id": "helix-4", 
-          "result": "unknown",
-          "measurement": 512.0,
-          "units": "bits/s"
-        } 
-      ], 
-      "analyzer_assigned_date": "2010-10-15T22:05:45Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000002",
-      "test_id": "double-helix"
-    },
-    {
-      "test_results": [
-        {
-          "test_case_id": "helix-0", 
-          "result": "pass"
-        }, 
-        {
-          "test_case_id": "helix-1", 
-          "result": "fail"
-        }, 
-        {
-          "test_case_id": "helix-2", 
-          "result": "skip"
-        }, 
-        {
-          "test_case_id": "helix-3", 
-          "result": "unknown"
-        }, 
-        {
-          "test_case_id": "helix-4", 
-          "result": "unknown",
-          "measurement": 512.0,
-          "units": "bits/s"
-        } 
-      ], 
-      "analyzer_assigned_date": "2010-10-15T22:06:46Z", 
-      "time_check_performed": false, 
-      "analyzer_assigned_uuid": "00000000-0000-0000-0000-000000000003",
-      "test_id": "double-helix"
-    }
-  ], 
-  "format": "Dashboard Bundle Format 1.0"
-}

=== removed directory 'examples/reports'
=== removed file 'examples/reports/data-views.html'
--- examples/reports/data-views.html	2011-05-03 20:36:45 +0000
+++ examples/reports/data-views.html	1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
-<div id="log"> </div>
-<script type="text/javascript">
-  $().dashboard("init", "{{API_URL}}", function(server) {
-    server.data_views(function(response) {
-      if (response.result) {
-        var log = $("#log");
-        log.append("<p>Available data views:</p><ul>");
-        $.each(response.result, function(index, data_view) {
-          log.append("<li>" + data_view.name + "</li>");
-        });
-        log.append("</ul>");
-      } else {
-        $("#log").append("<p>Unable to query for available data views:" + response.error + "</p>");
-      }
-    });
-  });
-</script>

=== removed file 'examples/reports/data-views.xml'
--- examples/reports/data-views.xml	2011-05-03 20:36:45 +0000
+++ examples/reports/data-views.xml	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-<data-report name="data-views">
-  <title>List of available data views</title>
-  <path>data-views.html</path>
-</data-report>

=== removed file 'examples/reports/hello-world.html'
--- examples/reports/hello-world.html	2011-05-03 20:36:45 +0000
+++ examples/reports/hello-world.html	1970-01-01 00:00:00 +0000
@@ -1,14 +0,0 @@
-<div id="log">
-  <p>Querying Dashboard API...</p>
-</div>
-<script type="text/javascript">
-  $().dashboard("init", "{{ API_URL }}", function(server) {
-    server.version(function(response) {
-      if (response.result) {
-        $("#log").append("<p>You are using Dashboard Server version " + response.result + "</p>");
-      } else {
-        $("#log").append("<p>Unable to check dashboard version: " + response.error + "</p>");
-      }
-    });
-  });
-</script>

=== removed file 'examples/reports/hello-world.xml'
--- examples/reports/hello-world.xml	2011-05-03 20:36:45 +0000
+++ examples/reports/hello-world.xml	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-<data-report name="hello-world">
-    <title>Basic example showing how to interact with the server using client side JavaScript API</title>
-    <path>hello-world.html</path>
-</data-report>

=== removed file 'examples/reports/query-data-view.html'
--- examples/reports/query-data-view.html	2011-05-03 20:36:45 +0000
+++ examples/reports/query-data-view.html	1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
-<h2>Data View</h2>
-<p>Please select the data view to query from the drop down list and click go to query it</p>
-<p>Queries with non-optional parameters are not yet supported</p>
-<form>
-  <label for="selector">Data view:</label>
-  <select id="selector"></select>
-  <button class="ui-widget" id="go">Go</button>
-</form>
-<h2>Response</h2>
-<div id="placeholder"></div>
-<script type="text/javascript">
-  $("#go").button({disable: true});
-  $().dashboard("init", "{{ API_URL }}", function (server) {
-    server.data_views(function (response) {
-      var options = $.map(response.result, function (data_view) {
-        return "<option value=\"" + data_view.name + "\">" + data_view.summary + "</option>";
-      });
-      $("#selector").append(options.join(''));
-      $("#go").click(function (ev) {
-        $("#go").button("disable");
-        var data_view_name = $("#selector").val();
-        server.query_data_view(function (response) {
-          //console.log("Got response", response);
-          if (response.error) {
-            alert(response.error.faultString);
-            //console.error("Unable to query data source", response.error.faultString); 
-          } else {
-            //console.log("Data source response", response.result);
-            $("#placeholder").dashboard("render_table", response.result);
-          }
-          $("#go").button("enable");
-        }, data_view_name, {});
-        return false;
-      });
-      $("#go").button("enable");
-    });
-  });
-</script>

=== removed file 'examples/reports/query-data-view.xml'
--- examples/reports/query-data-view.xml	2011-05-03 18:37:23 +0000
+++ examples/reports/query-data-view.xml	1970-01-01 00:00:00 +0000
@@ -1,4 +0,0 @@
-<data-report name="query-data-view">
-    <title>Example on how to get data from a data view</title>
-    <path>query-data-view.html</path>
-</data-report>

=== removed directory 'examples/views'
=== removed file 'examples/views/boards.xml'
--- examples/views/boards.xml	2011-04-29 09:43:42 +0000
+++ examples/views/boards.xml	1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
-<data-view name="boards">
-    <sql> 
-        SELECT DISTINCT
-            description AS "Board Description"
-        FROM
-            dashboard_app_hardwaredevice
-            INNER JOIN dashboard_app_testrun_devices ON (dashboard_app_testrun_devices.hardwaredevice_id = dashboard_app_hardwaredevice.id)
-            INNER JOIN dashboard_app_testrun ON (dashboard_app_testrun_devices.testrun_id = dashboard_app_testrun.id)
-            INNER JOIN dashboard_app_bundle ON (dashboard_app_testrun.bundle_id = dashboard_app_bundle.id)
-            INNER JOIN dashboard_app_bundlestream ON (dashboard_app_bundlestream.id = dashboard_app_bundle.bundle_stream_id)
-        WHERE
-             dashboard_app_bundlestream.pathname = <value name="pathname"/>
-             AND dashboard_app_hardwaredevice.device_type = 'device.board'
-    </sql>
-    <arguments>
-        <argument name="pathname" type="string" help="Pathname of a bundle stream to search"/>
-    </arguments>
-    <summary>
-        List unique descriptions of board devices in specific bundle stream
-    </summary>
-    <documentation>
-        This query joins the following tables: HardwareDevice + (many-to-many
-        helper) + TestRun + Bundle + BundleStream. The filtering depends on the
-        BundleStream.pathname property, the selected value is
-        HardwareDevice.description
-    </documentation>
-</data-view>

=== removed file 'examples/views/bundle-import-queue.xml'
--- examples/views/bundle-import-queue.xml	2011-05-02 17:34:10 +0000
+++ examples/views/bundle-import-queue.xml	1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
-<data-view name="bundle-import-queue">
-    <sql backend="sqlite">
-        SELECT
-            content_sha1 AS SHA1,
-            is_deserialized,
-            error_message
-        FROM
-            dashboard_app_bundle as Bundle
-            LEFT OUTER JOIN dashboard_app_bundledeserializationerror as BundleDeserializationError
-                ON BundleDeserializationError.bundle_id = Bundle.id
-         WHERE
-             Bundle.is_deserialized = 0
-             AND BundleDeserializationError.bundle_id IS NULL
-         ORDER BY
-             Bundle.uploaded_on
-    </sql>
-    <sql backend="postgresql">
-        SELECT
-            content_sha1 AS SHA1,
-            is_deserialized,
-            error_message
-        FROM
-            dashboard_app_bundle as Bundle
-            LEFT OUTER JOIN dashboard_app_bundledeserializationerror as BundleDeserializationError
-                ON BundleDeserializationError.bundle_id = Bundle.id
-         WHERE
-             Bundle.is_deserialized = false
-             AND BundleDeserializationError.bundle_id IS NULL
-         ORDER BY
-             Bundle.uploaded_on
-    </sql>
-    <summary>
-        List of bundles to deserialize
-    </summary>
-    <documentation>
-        List all bundles that are not deserialized and don't have an accompanying deserialization error. 
-    </documentation>
-</data-view>

=== removed file 'examples/views/bundles.xml'
--- examples/views/bundles.xml	2011-04-29 11:55:12 +0000
+++ examples/views/bundles.xml	1970-01-01 00:00:00 +0000
@@ -1,32 +0,0 @@
-<data-view name="bundles">
-    <sql backend="sqlite">
-        SELECT
-            content_sha1 AS SHA1,
-            content_filename AS "File Name",
-            uploaded_on As "Uploaded On",
-            ifnull(username, "(Anonymous)") AS "Uploaded By",
-            (CASE is_deserialized WHEN 1 THEN "yes" ELSE "no" END) AS "Is deserialzed?",
-            ifnull(error_message, "") AS "Deserialization Error"
-        FROM
-            dashboard_app_bundle as Bundle
-            INNER JOIN dashboard_app_bundlestream AS BundleStream
-                ON BundleStream.id = Bundle.bundle_stream_id
-            LEFT OUTER JOIN auth_user as User
-                ON Bundle.uploaded_by_id = User.id
-            LEFT OUTER JOIN dashboard_app_bundledeserializationerror as BundleDeserializationError
-                ON BundleDeserializationError.bundle_id = Bundle.id
-        WHERE
-             BundleStream.pathname = <value name="pathname"/>
-         ORDER BY
-             Bundle.uploaded_on
-    </sql>
-    <arguments>
-        <argument name="pathname" default="/anonymous/" type="string" help="Pathname of the bundle stream to list"/>
-    </arguments>
-    <summary>
-        List of bundles
-    </summary>
-    <documentation>
-        Re-implementation of the `lc-tool bundles` query with data-views
-    </documentation>
-</data-view>

=== removed file 'examples/views/streams.xml'
--- examples/views/streams.xml	2011-05-02 17:34:10 +0000
+++ examples/views/streams.xml	1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
-<data-view name="streams">
-    <sql>
-        SELECT
-            "BundleStream"."pathname" AS "Pathname"
-            ,(SELECT COUNT(*) FROM "dashboard_app_bundle" AS "Bundle" WHERE "Bundle"."bundle_stream_id" = "BundleStream"."id") AS "Number of bundles"
-            ,"BundleStream"."name" AS "Name"
-            ,"User"."username" AS "Owner"
-        FROM
-            "dashboard_app_bundlestream" AS "BundleStream"
-            INNER JOIN "auth_user" AS "User" ON ("BundleStream"."user_id" = "User"."id")
-        ORDER BY
-            "BundleStream"."pathname"
-    </sql>
-    <summary>
-        List of bundle streams
-    </summary>
-    <documentation>
-        Re-implementation of the `lc-tool streams` query with data-views. This
-        implementation also shows how it's possible to cross-reference user
-        information to display the owner of each stream.
-    </documentation>
-</data-view>

=== removed file 'examples/views/testruns.xml'
--- examples/views/testruns.xml	2011-04-29 10:34:04 +0000
+++ examples/views/testruns.xml	1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
-<data-view name="test-runs">
-    <sql> 
-        SELECT
-            analyzer_assigned_uuid AS "UUID"
-        FROM
-            dashboard_app_testrun
-            JOIN dashboard_app_bundle ON dashboard_app_testrun.bundle_id = dashboard_app_bundle.id
-            JOIN dashboard_app_bundlestream ON dashboard_app_bundlestream.id = dashboard_app_bundle.bundle_stream_id
-        WHERE
-             dashboard_app_bundlestream.pathname = <value name="pathname"/>
-    </sql>
-    <arguments>
-        <argument name="pathname" type="string" help="Pathname of a bundle stream to search"/>
-    </arguments>
-    <summary>
-        List all test run UUIDs in a specific bundle stream
-    </summary>
-    <documentation>
-        This query joins three tables: TestRun + Bundle + BundleStream. The
-        filtering depends on the BundleStream.pathname property, the selected
-        value is TestRun.analyzer_assigned_uuid.
-    </documentation>
-</data-view>

=== removed directory 'production'
=== removed file 'setup-dev-env.sh'
--- setup-dev-env.sh	2013-09-04 16:43:10 +0000
+++ setup-dev-env.sh	1970-01-01 00:00:00 +0000
@@ -1,97 +0,0 @@
-#!/bin/sh
-
-# Select development database backend (either sqlite or pgsql)
-export DEVEL_DB=${DEVEL_DB:-sqlite}
-
-# Use different port for postgresql so that both can co-exist
-if [ "x$PORT" = "x" ]; then
-    if [ "$DEVEL_DB" = "pgsql" ]; then
-        PORT=8001
-    else
-        PORT=8000
-    fi
-fi
-# Setup dashboard URL for lava-tool
-export DASHBOARD_URL=http://localhost:$PORT/dashboard
-# Find root directory
-ROOT="$(bzr root)"
-
-# Check if we should really wipe existing data
-if [ "x$1" = "x--force" ]; then
-    USED_FORCE=yes
-fi
-
-SQLITE_DB_LOCATION="$(python -c 'import lava_server.settings.development as settings; print settings.ROOT_DIR')/development.db"
-
-if [ "$USED_FORCE" != "yes" ] && [ "$DEVEL_DB" = "sqlite" ] && [ -e "$SQLITE_DB_LOCATION" ]; then
-    echo "Whoops, you already have a db, please move it aside first"
-    echo "You can use --force to *REMOVE* your database automatically"
-    exit 1
-elif [ "$USED_FORCE" != "yes" ] && [ "$DEVEL_DB" = "pgsql" ]; then
-    echo "PostgreSQL support is not so good yet, you have to pass --force"
-    echo "to let us know you want to wipe the devel database"
-    exit 1
-else
-    echo "Setting up hacking environment: "
-    if [ "$USED_FORCE" = "yes" ]; then
-        if [ "$DEVEL_DB" = "sqlite" ]; then
-            echo " * removing SQLite development database" 
-            rm -f "$SQLITE_DB_LOCATION"
-        else
-            echo " * removing PostgreSQL development database"
-            # Wipe postgres database 'devel' owned by user 'devel' with password 'devel'
-            PGPASSWORD=devel dropdb   --username devel --host localhost --no-password devel
-            echo " * creating fresh PostgreSQL development database"
-            PGPASSWORD=devel createdb --username devel --host localhost --no-password --encoding UTF-8 devel
-        fi
-        # TODO: Figure out how to re-enable this feature
-        # echo " * removing MEDIA files"
-        # rm -rf dashboard_server/media/$DEVEL_DB/
-    fi
-    echo " * building cache of static files (as symlinks)"
-    lava-server manage -d build_static --link --noinput --verbosity=0
-    echo " * creating fresh database"
-    lava-server manage -d syncdb --noinput -v0
-    lava-server manage -d migrate -v0
-    for FIXTURE_PATHNAME in $ROOT/dashboard_app/fixtures/hacking_*.json; do
-        FIXTURE=$(basename $FIXTURE_PATHNAME .json)
-        echo " * importing data: $FIXTURE"
-        lava-server manage -d loaddata -v0 $FIXTURE
-    done
-    echo " * starting development server in the background"
-    # Django debug server uses some thread magic to do autoreload. The problem
-    # is that it seems to spawn (multiprocessing?) another process that we
-    # cannot kill (yay for services on linux). Now that's a cheesy way to kill
-    # both reliably (or so it seems, I cannot explain it really). So yes, we
-    # spawn an xterm and sleep for a while. Shell engineering...
-    xterm -e lava-server manage -d runserver 0.0.0.0:$PORT &
-    SERVER_PID=$!
-    echo " * waiting for server to start up"
-    sleep 5
-    echo " * creating bundle stream for example data" 
-    lava-tool make-stream /anonymous/examples/ --name "Demo content loaded from examples/bundles"
-    for BUNDLE_PATHNAME in $ROOT/examples/bundles/*.json; do
-        BUNDLE=$(basename $BUNDLE_PATHNAME .json)
-        echo " * importing bundle: $BUNDLE"
-        lava-tool put $BUNDLE_PATHNAME >/dev/null
-    done
-    for BUNDLE_PATHNAME in $ROOT/examples/bundles/templates/*.json; do
-        BUNDLE=$(basename $BUNDLE_PATHNAME .json)
-        echo " * importing bundle template: $BUNDLE"
-        for i in $(seq 1 20); do
-            sed "$BUNDLE_PATHNAME" -e "s!@TEMPLATE@!$(printf %04d $i)!g" > "$i-$BUNDLE"
-            lava-tool put "$i-$BUNDLE" /anonymous/examples/ >/dev/null
-            rm -f "$i-$BUNDLE"
-        done
-    done
-    echo " * shutting down development server"
-    kill -TERM $SERVER_PID
-    echo "All done!"
-    echo
-    echo "To get started run:"
-    echo "   DEVEL_DB=$DEVEL_DB lava-server manage -d runserver 0.0.0.0:$PORT"
-    echo
-    echo "Remeber, username: admin"
-    echo "         password: admin"
-fi
-

=== removed file 'setup.cfg'
--- setup.cfg	2011-06-28 11:40:16 +0000
+++ setup.cfg	1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
-[upload_docs]
-upload-dir=build/sphinx/html
-
-[upload]
-sign=True

=== removed file 'setup.py'
--- setup.py	2013-01-31 02:52:51 +0000
+++ setup.py	1970-01-01 00:00:00 +0000
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# Copyright (C) 2010 Linaro Limited
-#
-# Author: Zygmunt Krynicki <zygmunt.krynicki@linaro.org>
-#
-# This file is part of Launch Control.
-#
-# Launch Control is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License version 3
-# as published by the Free Software Foundation
-#
-# Launch Control is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with Launch Control.  If not, see <http://www.gnu.org/licenses/>.
-
-from setuptools import setup, find_packages
-
-
-setup(
-    name='lava-dashboard',
-    version=":versiontools:dashboard_app:__version__",
-    author="Zygmunt Krynicki",
-    author_email="zygmunt.krynicki@linaro.org",
-    packages=find_packages(),
-    license="AGPL",
-    description="Validation Dashboard for LAVA Server",
-    long_description="""
-    Validation Dashboard is a repository for test results.
-    """,
-    url='https://launchpad.net/lava-dashboard',
-    #test_suite='dashboard_app.tests.test_suite',
-    entry_points="""
-        [lava_server.extensions]
-        dashboard=dashboard_app.extension:DashboardExtension
-        """,
-    classifiers=[
-        "Development Status :: 3 - Alpha",
-        "Intended Audience :: Developers",
-        "License :: OSI Approved :: GNU Affero General Public License v3",
-        "Operating System :: OS Independent",
-        "Programming Language :: Python :: 2.6",
-        "Programming Language :: Python :: 2.7",
-        "Topic :: Software Development :: Testing",
-    ],
-    install_requires=[
-        'Django >= 1.2',
-        'django-restricted-resource >= 0.2.6',
-        'docutils >= 0.6',
-        'lava-server >= 0.8',
-        'linaro-dashboard-bundle >= 1.8',
-        'linaro-django-pagination >= 2.0.2',
-        'linaro-django-xmlrpc >= 0.4',
-        'pygments >= 1.2',
-        'south >= 0.7.3',
-        'versiontools >= 1.8',
-    ],
-    setup_requires=[
-        'versiontools >= 1.8',
-    ],
-    tests_require=[
-        'django-testscenarios >= 0.7.1',
-        'mocker >= 1.0',
-    ],
-    zip_safe=False,
-    include_package_data=True
-)
-

=== removed file 'test.sh'
--- test.sh	2011-03-16 21:21:26 +0000
+++ test.sh	1970-01-01 00:00:00 +0000
@@ -1,13 +0,0 @@
-#!/bin/sh
-
-echo "Testing script for Launch Control"
-export DEVEL_DB
-for DEVEL_DB in sqlite pgsql; do
-    echo " * removing old uploaded content"
-    rm -rf dashboard_server/media/$DEVEL_DB
-    echo " * running tests for $DEVEL_DB"
-    ./dashboard_server/manage.py test -v0 --failfast
-    echo " * listing leftover attachments and bundles "
-    find dashboard_server/media/$DEVEL_DB/bundles
-    find dashboard_server/media/$DEVEL_DB/attachments
-done

