* Adds a common function for video/image hooks
* Adds support for modal + placeholder html text + title
* Multiple modals on the same page
* Close modals with escape or by clicking on overlay
* Remove category-picking UI from translate page.
* Tighten up a test whose failure took me a long time to diagnose.
* Clarify the limitations of _inherit descriptor factory.
* (Per request) validate category value, in addition to its requiredness, on save().
* Added a new migration for gallery permissions: add, change, delete
* Draft titles are now abstracted to a constant and a function, get_draft_title
* Edits set the updated_by field
* Use ModelForm.save() when saving drafts.
* Add a delete confirmation page and refactor some CSS to share to-delete styling.
* Fix a JS error in safari, .delete property is reserved
* Fix draft form error display and some string changes for the upload form.
* Adds a modal form that runs the user step by step through the upload process, as described in http://people.mozilla.com/~chowse/drop/sumo/kb/v7/toolbox/03_media_gallery.png
* Extracts the code for wrapping inputs in forms and POSTing to iframes from upload.js into libs/jquery.ajaxupload.js
* During image upload, a user can cancel or edit the metadata (title, locale, description).
* Cancelling or uploading an invalid image changes the hint message above the image.
* Neat fact of the day: cancelling an iframe from loading can be done by changing it's src to null in JavaScript.
* This form does not work with JavaScript disabled. Must it?
* Modal form automatically opens if drafts exist
* No video upload validation yet.
* Simplify gallery urls.py
* Disable submit button while uploading
* Bug 607959 - "History" tab stays highlighted when comparing revisions.
* Bug 607962 - Fix search box width on Linux.
* Bug 608849 - Fix old-style sidebar on AoA.
* Bug 610359 - Fix home page layout on Linux.
* Bug 610672 - Update link to mobile and use url() in the header.
* Bug 610699 - Make the dotted border on the homepage bigger.
* Bug 610703 - Use MetaBlack for <mark> in headings.
* Handle OS->Browser dependency (only show browsers available for selected OS) [bug 609325]
* Redirect mobile home->desktop home when desktop OS is selected, and vice-versa.
* Initialize the showfor selector widget only when necessary and after the values have been set in initForTags(). [bug 610701]
* Contributor and L10n Dashes are very similar. Factor up the common parts.
* Give the L10N_READOUTS constant sole discretion on what appears on the main L10n dash. I had given the template control for more flexibility, but even in this small case, I managed to get some IDs desynced, which broke a few intra-page links. As a result, add short_title and details_link_text attrs to readouts, and change L10N_READOUTS to a SortedDict.
* Add a locale arg to Readout constructor which can override the one in request. This lets the Contributor Dash always show English data, independent of what language the UI is in.
This adds a task that spawns seperate, child tasks that re-render the
knowledge base in 100-document chunks. It also adds a number of helpers
to access the main task. (wiki.tasks.rebuild_kb) The main task is rate-
limited to once every 20 minutes. The chunks are not rate limited right
now.
* settings.WIKI_REBUILD_ON_DEMAND
- There may be cases, like a KB sprint, where it's more efficient to
do periodic KB rebuilds. This setting (when False) disables all on-
demand (e.g.: triggered through the app) rebuilds.
* wiki.tasks.schedule_rebuild_kb
- This method will try to queue a rebuild_kb task provided certain
conditions are met:
* settings.WIKI_REBUILD_ON_DEMAND is True
* There is not another queued rebuild_kb task.
If both of these are true, queue a task and set the lock. (When a
rebuild_kb task starts, it clears the lock.)
* wiki.views._maybe_schedule_rebuild(form)
- When editing an existing document, we only need to rebuild if the
title or slug has changed. This checks form.changed_data for either
field, then calls schedule_rebuild_kb() if necessary.
* wiki.cron.rebuild_kb
- For those times when on-demand rebuilds are too frequent, we can
schedule this cron, which just fires off the rebuild_kb task.
I took the absolute minimun change to make this work, leaving the
Document.allows_revision_by method in place, in case we do end up with
different permissions for, e.g., templates.
If that code rots for a while and it looks like we'll never do that,
we can take a bigger patch when there's more time and remove it
completely.
* Fix <summary> styling on translate.html.
* The list of l10n dashboard readouts with detail views is now managed by readouts.py, since it's in a position to know.
* Started moving un-common parts of the Outdated/Untranslated template out; it looks like we're going to be able to reuse that one table for almost everything. The template will probably get renamed and CSS rules generalized when my verbal center comes back online.
This has two parts:
* A RelatedDocument model/table that's used to store document relatedness.
* A cron job that populates the table as efficiently as it can.
The cron can run hourly/daily/whatever makes sense. (Maybe during a KB sprint
we can crank it up and normally we can turn it back down.)
The cron does need to run on the master because it does an INSERT...SELECT.
* Convert latin1 tables to utf8 (also give them an explicit collation)
* Add settings for max filename length and validate the form against them.
* Add form validation messages.
* Uploading images through ajax now works (iframe access was denied).
* Alter all filename fields in the db to increase the max_length.
* Organize upload tests better.
* Update grid view and individual media file view to match chowse's mockups.
* Get rid of the gallery base.html template and use the wiki one.
* No more ?locale query param, just switch the site language
* Add generic autosubmit selects, initialized in main.js
Created a new app because it involves multiple views and a cron. The
cron will need to be set up to run once/minute. It does a proxy request
to the chat server (settings.CHAT_SERVER) to get the queue status, then
stores the result in the cache (settings.CHAT_CACHE_KEY). The
/chat/queue-status/ view dumps out whatever's in the cache or returns a
503 status if the cache is empty.
Among the other changes to the KB, while PHP's urldecode() maps + to a
space, Django does not. Hence all the old URLs had + in place of %20.
This middleware checks the path for +s, and redirects with %20s if it
finds any. It doesn't touch the query string.
Because django.views.generic.simple.redirect_to requires a full URL and
it's too early to call reverse() at that point, I've added a simple
view, sumo.views.redirect_to that behaves similarly. I've included
tests for the new view, as well as testing the specific redirect.
* Markup, CSS, templates, and queries for the Overview and Untranslated Articles localization summaries are in place, though there's still some optimization to do.
* Add a `number()` template function for localized thousands formatting, etc.
* Stub out Contributors Dash view just so we can reverse() to it.
* Add trivial tests. Perhaps horrific ones testing the accuracy of the queries will follow. Perhaps.
* To come: WebTrends integration and the rest of the dashboard readouts
Create a new home page at /home/ that pulls in editable content from
the wiki. Involves some tweaks to the wiki templates. Also add the rest
of the KB categories.
* Hard coded top side can be localized with gettext
* Not tested for IE
* Migration to create initial templates
* Inherits from wiki base template
As the new design propagates to the rest of the site, we need to make
the common/layout templates the base of both wiki and home page.
* Hide "Allow translations" for documents with existing translations since you can't disallow them.
* Disable the "Localize" side tab if document is not localizable.
* Add Document.save checks for disallowing children if self is not localizable.
* Also politely check and break if trying to disallow children on a document which already has some.
The {{ csrf() }} function doesn't work inside Jinja2 macros. I think
they don't have the correct context. (Even passing request to the macro
didn't help.)
Keep an eye out for it.
Adds a `kbforums` app, which is a clone of the `forums` app with a few
tweaks:
* The top-level `Forum` model is replaced by `wiki.models.Document`.
* The permissions have been simplified. There are no per-document forum
permissions.
* The `Document` does not track its `last_post`.
* `Post.author` has been renamed to `Post.creator` following our ad hoc
standard.
* The ability to override `Post.created` and `Post.updated`, only used
in the data migration, is gone.
* Moving threads is gone. This needs more thought, and moving to the
`forums` app is non-trivial.
* Attempting to visit the translate view in the en-US locale no longer 404s; it now helpfully redirects to the edit view.
* Trying to translate an unapproved document now shows an error (though this has to change again (see bug 604466).
* It is no longer permitted to make a new document in a non-default locale. (This test is temporarily skipped and should be reinstated when we get the "non-localizable" bool on Document and thus get this ability back.)
* Document.save() now raises a ValidationError if you try to save a parentless article that's not in the default locale.
* Revised translate.html. Tweaked labels to reflect that we no longer always show the latest revision. Diff now compares the English version the current translation is based on and the current English version so translators can see what has changed in the English article since it was last translated.
* errorlist.html now displays non-field errors as well.
* Add an "original" property to Document as a shortcut for finding the English version.
* wiki.tests.TestCaseBase no longer unnecessarily clears the cache.
* Removed a duplicate test.
* Refactored doc_rev() to RepeatOurselves less.
* Revision's string representation now includes the revision ID: handy for debugging.
* fall back if locale-specified version does not exist.
* return message if English version does not exist either.
* make wiki_to_html() and parse() receive and pass around locale
* Similar to video migration
* Generates thumbnails
* Shrinks down the image if the image is too large
* Skips and warns if file is not an actual image
TODOs:
* Refactor the right side vertical tabs to be reusable across pages (macro?)
* Some js/css to convert showfor <select/>'s to dhtml widget
* Try to make the Related Articles and TOC horizontal separator w/o image
* Try to make the fading article rounded border (top right) w/o images?
* Lots of <a />'s with src="#"
* IE*!!!
* Does not tolerate lonely ogg files
* Resumes migration from where it left off
* Tested on 128 videos copied from our cdn, videos.mozilla.org
* Rewrite upload.utils to avoid passing around max_file_size parameter
* Removed unnecessary test for create_imageattachment (functionality already covered in check_file_size test)
* The new_revision form is now 2 forms: one for versioned data and one for document-scoped metadata. This supports the UI revision that takes our final agreed-upon requirements into account.
* Redirects now start numbering at "Some Title Redirect 1" rather than "Some Title Redirect 2". I don't know what I was thinking before.
* Document.allows_editing_by() is now called allows_revision_by(), freeing up the name "allows_editing_by" to mean "non-versioned document metadata can be edited by".
* Stick <article> tags around wiki document content for syndication niceness and the ability to use H1s.
* Rename new_revision view to edit_document, since it does more than make new revisions now.
* There was some repetition every time we saved a RevisionForm. Factored it and some existing helper procs into RevisionForm.save().
* Turn the _process_doc_form() helper into an overloaded DocumentForm.save().
* Videos are identified by title and locale
* Depends on an update in py-wikimarkup which adds support for <video> and <source> tags (py-wikimarkup commit cc06e6d264622891b6b018e8670c9ef4bb12d618)
* Attaches all the _hook_*s to the WikiParser class, because they need a contextual locale.
* Adds locale support for any of the hooks that do document lookup.
* Uses SWFobject JS lib to support flash fallback for video.
* Adds a migration for unique ('locale', 'title') on gallery_video and gallery_image
* Adds a WIKI_VIDEO_WIDTH|HEIGHT constant that may be used as MAX_WIDTH|HEIGHT in the future, once we get video thumbnails.
Consequently...
* Reordered a few XML strings in tests to conform to actual output. We really need an easy to compare XML trees.
* Made a test less brittle.
* Do automatic redirect creation on retitling and restubbing. Avoid collisions with existing document titles and slugs.
* Implement content-injection-safe backlinks to redirect pages from the pages they redirect to. Implement redirect suppression so you can stay at (and edit) the redirect once you get there.
* Fix a template bug where the browser and OS choosers wouldn't show up on documents that had no approved content.
* Delete "parent" from a translate.html, which I don't think was supposed to be there.
* document() helper once again respects a slug kwarg if provided.
* Remove pointless html kwarg from doc_rev helper function. The passed-in HTML always got paved over immediately.
* Add @require_GET to some views that assume the GET method.
* Hoist doc_rev up to wiki.tests.
To come: UI for changing the slug and title of documents
* Prompt for and store commit message.
* Don't store review message in revision, it will be sent in the notification.
* Refactored modals activated on button click (edit submit, translation submit, review message).
Also switch to namedtuples for several tuples that were getting too big for their britches. Now we don't have to continually add items to unpacks all over the app when tuples grow.
Cookies to come.
* Add JS that obeys the {for} tags, showing and hiding the proper page elements.
* Strip whitespace off {for} parameters in the parser so JS doesn't have to tolerate it.
* Generate a TOC in JS, taking what's visible into account. Add just enough TOC CSS that I can stand to look at it.
* Build UI for choosing {for} OS. Page and TOC update according to choice. Use semantically correct <select>s for the OS and browser selectors. We can style as desired. Split into optgroups as per the mockup. Show the OS/browser selectors even when JS is off--just to indicate what's currently shown--but they're disabled.
* Tweak CSS to not color non-href anchors blue.
* The SUMO team tends to write per-browser content only in broad strokes, encompassing many versions. Thus, made the {for} stuff use the same FF version enum as the article search does. It lines up perfectly with current use and is simple.
* Stop repeating an OS enum: start using the one we already had in models.
* Add alternating numbering styles for TOC entries after consulting with chowse.
* Couple filteredFors() to the page: it didn't end up being useful for the TOC builder, and this simplifies it.
* To come later: sniffing and cookies.
* Add support for {for} tags: swapping tags for something the wiki formatter will consider inline, running the formatter, replacing the tags, balancing them properly to tolerate user error (since there can be no such thing as invalid wiki markup), and finally choosing whether to make each showfor a div or a span. Nesting showfors works fine.
* Move Knowledgebase-specific wiki parser stuff into wiki.parser.
* Change default value of sumo.parser.WikiParser.parse's show_toc arg to match wikimarkup's.
* Move the sumo app's wiki_to_html() into its parser module to match the placement of the one in the wiki app.
This is in preparation for showfor implementation, which uses a custom tag handler, which receives a copy of the parser when called. With the previous composition-based wrapping, the uncustomized parser would be passed to the tag handler, and any markup inside the tag would be parsed in an un-SUMO-like fashion.
* Raise FixtureMissingError in test helpers, e.g. on creating media gallery image and wiki revision, instead of creating testuser
* Add ImageUploadForm and VideoUploadForm
* Simplify gallery app's urls.py
* Adds a bunch of gallery utils to create and upload media
* Adds two views up_media_async, del_media_async
* Rename upload_images to upload_imageattachments
* Define a more generic upload_media function to be used by the gallery app
* Document some of our coding conventions
* Add a migration for the video model
* Define a MAX_FILESIZE for video uploads (16 megabytes), overwritable in settings_local.py
* Templates are simply documents with title.startswith('Template:')
* Template args are not wiki parsed
* Document.save() keeps is_template in sync with document.title
* Add a migration for the new is_template column
* Turn {note}{/note} into <div class="note"></div>, and similarly for {warning}
* Turn {menu This is a menu item} into <span class="menu">This is a menu item</span>
* Turn {key X} into <span class="key">X</span>
* Expand {key ctrl+alt+X} into <span class="key">ctrl + <span class="key">alt</span> + <span class="key">X</span>
* Allow for inline templates (there is a check for templates containing newlines in hook_template)
Includes:
* migrations for the models
* a shared abstract model Media for the concrete Image and Video models
* restricting locale choices in the gallery and wiki models
* some check.py complaints and cleanup
* a documentation section for production regarding upload paths
* Also checks for existence of document in parser._getWikiLink
* Add JS support for slug. Uses django's URLify function combined with their jQuery plugin, prepopulate
* Add migration 35 to add the slug column to the model
* Using django's urlquote/urlencode and removing our related sumo tests
* Don't save thumbnail twice, wait until it's generated.
* [590004] Fixes foreign key leakage in tests - test_utils.TransactionTestCase truncated django_content_type. Landed a fix in test_utils and added a setting to use it, TEST_UTILS_NO_TRUNCATE
* No more SkipTests in the upload app. Hoping Hudson shows mercy and passes all of them this time.
* Change ImageAttachment docstring to reflect reality.
* Make LocaleURLMiddleware clean up after itself: clear the thread-local prefixer variable that it sets before the request. Tests can now run in any order without the thread-local setting of one influencing the next. This also uncovers a lot of buggy tests which were mistakenly depending on the work of previous ones. Much of the rest of this changeset is toward fixing these.... A good test to compare before and after this commit is `test_json_callback_validation`. Run it alone, and LocaleMiddleware tosses us a 301 because we don't have a locale prefix set. Run it in concert with other tests, and somebody else sets the thread-local for it.
* Added `LocalizingClient`, which provides the functionality of django.test.client.Client but implicitly prepends a locale code to anything you request. This saves dodging the initial 301 that LocaleURLMiddleware returns in response to an un-prepended request. It also makes "priming" the middleware by doing an initial arbitrary request unnecessary (and ineffective, since the middleware no longer leaks state). Removed all instances of such priming.
* Switched many tests to use `LocalizingClient`. Some uses of plain `Client` remain, but those are correct, since they test things like the middleware's 301s.
* Renamed `set_url_prefix` and `get_url_prefix` to better reflect their purpose: they hold Prefixers, not prefixes.
* Added a `force_locale` kwarg to `sumo.urlresolvers.reverse()`, which forces the same default locale as would normally be used by the middleware to be prepended onto the result, even if there is no prefixer set. This is useful when you need to get a reversed URL against which to compare a 301's Location in a test.
* Moved `split_path()` out of `Prefixer`, since it needs no instance state and I needed it in `LocalizingClient`.
* `Prefixer` can now be instantiated without a request, in which case it defaults to a fairly blank one and returns results largely determined by `settings.LANGUAGE_CODE`.
* Fixed a gabillion other tests. I like to think I understood each one's intent before causing it to pass, but extra eyes are certainly welcome.
* Fixed some pyflakes violations: semicolons, whitespace, unused imports, etc.
test_utils.TestCase also adds an instrumented Jinja render() method so we can assert things about request.context, which contains what's passed into templates.
* Make LocaleURLMiddleware clean up after itself: clear the thread-local prefixer variable that it sets before the request. Tests can now run in any order without the thread-local setting of one influencing the next. This also uncovers a lot of buggy tests which were mistakenly depending on the work of previous ones. Much of the rest of this changeset is toward fixing these.... A good test to compare before and after this commit is `test_json_callback_validation`. Run it alone, and LocaleMiddleware tosses us a 301 because we don't have a locale prefix set. Run it in concert with other tests, and somebody else sets the thread-local for it.
* Added `LocalizingClient`, which provides the functionality of django.test.client.Client but implicitly prepends a locale code to anything you request. This saves dodging the initial 301 that LocaleURLMiddleware returns in response to an un-prepended request. It also makes "priming" the middleware by doing an initial arbitrary request unnecessary (and ineffective, since the middleware no longer leaks state). Removed all instances of such priming.
* Switched many tests to use `LocalizingClient`. Some uses of plain `Client` remain, but those are correct, since they test things like the middleware's 301s.
* Renamed `set_url_prefix` and `get_url_prefix` to better reflect their purpose: they hold Prefixers, not prefixes.
* Added a `force_locale` kwarg to `sumo.urlresolvers.reverse()`, which forces the same default locale as would normally be used by the middleware to be prepended onto the result, even if there is no prefixer set. This is useful when you need to get a reversed URL against which to compare a 301's Location in a test.
* Moved `split_path()` out of `Prefixer`, since it needs no instance state and I needed it in `LocalizingClient`.
* `Prefixer` can now be instantiated without a request, in which case it defaults to a fairly blank one and returns results largely determined by `settings.LANGUAGE_CODE`.
* Stopped expecting locale prefixes in wiki parser tests: the parser is being run outside any request and so should return unlocalized URLs.
* Ripped `get_url` off the legacy `Forum` and `ForumThread` models and deleted its tests. This was a lot faster than trying to fix them, and the entire models are dying for 2.3 anyway.
* Fixed a gabillion other tests. I like to think I understood each one's intent before causing it to pass, but extra eyes are certainly welcome.
* Fixed some pyflakes violations: semicolons, whitespace, unused imports, etc.
* New document
* New revision (== edit document)
* Document revision history
* Document list by category
* All documents list
TODO: Build them all up and polish!
Depends on a fix in py-wikimarkup which makes the parser instantiatable.
* parser refactoring for optional wiki_hooks
* inside-function imports to avoid circular importing
* revision save updates document's html, if the revision is more recent
* make hooks pep8er (use _ instead of camelCase)
* move _document and _revision to wiki/tests/__init__.py
* make new document URL be identical to existing document URL
* use from |django.conf import settings| instead of |import settings| everywhere
* move get and post lambdas to sumo/tests/__init__.py
Other minor improvements:
* Move content_parsed to Document and comment it out. Whoever needs it can uncomment and test it.
* Rename parent inverse relationship to "translations".
* Start testing operating_systems attr.
If you already ran 31-wiki-app, drop the wiki_document and wiki_revision tables before running 32-wiki-app.
Also:
* Index OS and FF version values, since we'll want to filter by those for document listings.
* Move content_parsed property to Document (which makes more sense), and comment it out. Whoever needs it can uncomment and test it.
* Change table types to InnoDB and charset to utf8.
A forum not having one of the new permissions defined on it via django-authority is considered to grant that permission to the world. (The auth backends we're using have no concept of granting a permission to the world.)
Also:
* cleans up a TODO for edit question in the flagged_question.html template.
* checks if content_object is set before attempting to show it. Downside is that we won't find integrity errors if they occur otherwise, but those shouldn't occur in the first place.