Compare commits

...

3166 Commits
1.5.x ... 1.6.0

Author SHA1 Message Date
Tim Abbott
2e9f469c9a Release Zulip Server 1.6.0. 2017-06-06 16:57:10 -07:00
Tim Abbott
b286a4210e docs: Update release checklist. 2017-06-06 14:20:13 -07:00
Tim Abbott
acc83a3fcc locale: Update a few last translation strings. 2017-06-06 13:57:08 -07:00
Tim Abbott
45c47aff34 travis: Remove unnecessary nvm install step.
This was needed before Zulip switched to using a pinned node version.
2017-06-06 13:39:51 -07:00
Tim Abbott
2215af4b57 docs: Add a bunch of documentation on Travis CI. 2017-06-06 13:39:51 -07:00
Tim Abbott
16a54ad837 locale: Update German and Spanish strings. 2017-06-06 12:56:53 -07:00
Tim Abbott
f7b604f9be webhooks: Fix unnecessary/buggy translation string. 2017-06-06 11:59:36 -07:00
Tim Abbott
968f65686f locale: Update strings for Zulip 1.6 release. 2017-06-06 11:54:28 -07:00
Tim Abbott
ec6abddc38 portico: Remove obsolete code for Zulip open sourcing announcement.
This was only ever used on the old zulip.com.
2017-06-06 11:36:03 -07:00
Greg Price
4165c9a62e apps: Link directly to the upstream /apps page.
Now that this page redirects to upstream, make our own links
to it point directly upstream.  This saves a redirect, and
makes it more transparent where the link points if the user
examines it before following.
2017-06-06 11:21:20 -07:00
Greg Price
04b363f3a2 apps: Redirect /apps -> zulipchat.com/apps, except on upstream itself.
This page describes software the user will get from upstream for
their own devices, independent of what's on the server they're
using.  So it should live in a place maintained together with
that other software, rather than be distributed and versioned
with the server.

The use of ZILENCER_ENABLED to tell the difference is rather a hack
but is currently how we do this in the small handful of similar
spots; see #5245.

Fixes #5234.
2017-06-06 11:21:20 -07:00
Greg Price
c78bfc356f apps: Stop distinguishing an SSO-only desktop app.
The "new" Electron desktop app has only one build, so link to it
unconditionally.
2017-06-06 11:21:20 -07:00
Jack Zhang
84e5fe733c message-editing: Show date lines between edits from different days.
Added show_date_row field to each item of content_edit_history.
We use date lines to separate events that happened on different days.

Fixes #4638.
2017-06-06 11:04:30 -07:00
Jack Zhang
0534a4c42d message-editing: Optimize timestamp format to display only hours & minutes 2017-06-06 11:03:37 -07:00
derAnfaenger
64ab1080dc docs: Update directory-structure.md with new bots dirs. 2017-06-06 08:51:16 -07:00
derAnfaenger
a596878fe1 docs: Fix header structure in bots-guide.md. 2017-06-06 08:51:16 -07:00
Cynthia Lin
8e0b1bec9d bookend: Remove .sea-green class for Unsubscribe state. 2017-06-06 08:31:09 -07:00
Umair Khan
1d183eabf1 testing: Write the .coverage file.
We need to call save explicitly to make coverage write the
.coverage file.
2017-06-06 08:03:30 -07:00
Umair Khan
a926559889 testing: Use concurrency parameter.
Coverage includes a concurrency parameter which can be used
to track files if multiprocessing is used.
2017-06-06 08:03:25 -07:00
Umair Khan
b09b60dfff Revert "test-backend: Enable test coverage in multi-process mode."
This reverts commit a22d6d2c2a.
2017-06-06 13:07:16 +05:00
Tim Abbott
d18e0bcdca log2zulip: Fix paths to the rest of the project. 2017-06-05 23:48:31 -07:00
rht
486e4e30da Update 'OS X' reference to macOS. 2017-06-05 22:11:34 -07:00
Tim Abbott
bbbd924bdf bookend: Add i18n tags for bookend notices. 2017-06-05 16:55:56 -07:00
Cynthia Lin
11e68606b4 design: Improve design of Subscribe/Unsubscribe buttons in message view.
Tweaked by tabbott to use an existing button style.

Fixes #5196.
2017-06-05 16:55:56 -07:00
Tim Abbott
b89be3f54b bookend: Make ordering of subscribe bookends consistent.
Previously, if we had both a date and a subscribe bookend, they would
appear in one order after new messages were sent (bookend_bottom of
the top group), and another after a reload (bookend_top of the bottom
group).  This makes the experience consistently a bookend_top.
2017-06-05 16:43:26 -07:00
Tim Abbott
70d414b62c bookend: Switch whitespace from padding to margin.
This creates more consistent spacing for bookends in relation to
actual message groups.
2017-06-05 16:27:57 -07:00
Tim Abbott
235bf65668 bookend: Only show bookend buttons in trailing bookends.
Apparently, this template was just always missing this check.

Fixes #5237.
2017-06-05 16:27:57 -07:00
Tim Abbott
113b64ad4b bookend: Add missing i18n tags on bookends. 2017-06-05 16:27:57 -07:00
Cynthia Lin
b561b19d24 settings: Add notice for non-admin users about read-only access.
With contributions from Brock Whittaker and Tim Abbott.

Fixes #5165.
2017-06-05 15:41:36 -07:00
Tim Abbott
f724c0fbd3 hotkey: Fix 'P' hotkey narrowing to use first unread message.
Previously, this hotkey was not correctly using the use_first_unread
option, and thus would take you to the close to your pointer, not your
first unread private message.

Fixes #5238.
2017-06-05 15:21:47 -07:00
Abhijeet Kaur
46883c5c0d bots: Add test file for 'giphy' bot.
This bot replies with different gif for the same query
that is provided. Mocked a definite response from requests.get
function.
2017-06-05 15:11:46 -07:00
Tim Abbott
96c75db558 bots: Refactor bot testing library to still support un-mocked HTTP.
Several of our bots haven't been converted to have mock responses for
third-party APIs yet, and we may want that code path for with-network
testing anyway.
2017-06-05 15:11:46 -07:00
Abhijeet Kaur
bcc4ced413 bots: Add mock test support for bots using internet services.
Mock requests.get function for bots relying on external services
which may return different results. 'http_response' is mocked to
check if the bots run well and to make the tests determinitic. The
code first checks if the http request corresponding to the http response
is called or not.

This commit renders test files of bots using the internet
(third party) services to Fail. As requests.get() is replaced
by our mock function.

Since we have not provided mock http response for bots like xkcd,
wikipedia, define etc. Their requests.get() function returns empty
message.
2017-06-05 15:11:24 -07:00
Cynthia Lin
dd1f3cfcb6 hotkeys: Include .editable-section in processing_text().
Prevents accidental hotkey triggering while span.editable-section is
focused.  Fixes #5232.
2017-06-05 13:46:37 -07:00
Eeshan Garg
ffb3994b4e webhooks/bitbucket: Migrate docs to Markdown. 2017-06-05 11:22:06 -07:00
Eeshan Garg
def4650d84 webhooks/beanstalk: Migrate docs to Markdown. 2017-06-05 11:22:06 -07:00
Eeshan Garg
3c47efb1fc templates: Add macro for appending branches to webhook URLs.
This macro is an alternative to git-webhook-url-with-branches.md,
which contains the full URL with a `branches` query parameter at
the end. This macro is for when we just want to specify that this
can be done but the URL to append to can be variable or is unique
to a particular integration (and thus, doesn't warrant its own
macro and a full URL example).
2017-06-05 11:22:06 -07:00
Eeshan Garg
433686457a templates: Add Markdown macro for URLs with bot_email@api_key. 2017-06-05 11:22:06 -07:00
Eeshan Garg
0cfe089152 webhooks/github: Migrate docs to Markdown. 2017-06-05 11:22:06 -07:00
Eeshan Garg
7cfc592202 webhooks/bitbucket2: Migrate docs to Markdown.
The change to `render_markdown_path` in `app_filters.py` was
required because for bitbucket2, `integrations.name` is
`bitbucket2`, which is substituted for the stream name in our
Markdown macros. It didn't make sense to recommend the name
`bitbucket2` as a default stream name to our users (for them,
it's just bitbucket). However, the URL is still
`api/v1/external/bitbucket2`.
2017-06-05 11:22:05 -07:00
Eeshan Garg
2f28b3d35b webhooks/gogs: Migrate docs to Markdown. 2017-06-05 11:22:05 -07:00
Eeshan Garg
a12fe65166 webhooks/gitlab: Migrate docs to Markdown. 2017-06-05 11:22:04 -07:00
Eeshan Garg
dd15b2d997 github_webhook: Migrate docs to Markdown. 2017-06-05 11:20:49 -07:00
Eeshan Garg
fab20ec6fd templates: Add macro for appending branch names to Git webhook URLs. 2017-06-05 11:20:48 -07:00
Eeshan Garg
ae8eb14e5a integrations: Specify a generic URL in GithubIntegration.
We now supply a generic URL for our legacy and webhook GitHub
integrations, as opposed to a dynamically generated URLs
for all other WebhookIntegration(s). Previously, within
GithubIntegration, an invalid URL was dynamically generated
which wasn't even used. Now, we just manually supply the URL
to GithubIntegration.

Furthermore, we'll now be able to access the correct URL in
`render_markdown_path` for our macros.
2017-06-05 11:19:57 -07:00
Vaida Plankyte
5fe7ed8afa settings: Make notification settings header consistent.
Fixes #5172.
2017-06-05 10:37:05 -07:00
Steve Howell
0d08edc6b6 docs: Add note about tools/linter_lib to lint docs. 2017-06-05 09:20:21 -07:00
Steve Howell
a606628b16 Extract tools/linter_lib/pep8.py 2017-06-05 09:20:21 -07:00
Steve Howell
9fab41aebb Extract tools/linter_lib/pyflakes.py 2017-06-05 09:20:21 -07:00
Steve Howell
29affda956 Extract tools/linter_lib/exclude.py 2017-06-05 09:20:21 -07:00
Steve Howell
40a2ffad98 Extract tools/linter_lib/custom_check.py.
As part of extracting this, we exempt the library from all custom
checks on itself.  This is expedient, since a lot of our
custom checks are naive about whether things are in strings, and
it is also a pain to configure individual rules.
2017-06-05 09:20:21 -07:00
Steve Howell
8ee50f019b lint: Add "nolint" handling for custom checks. 2017-06-05 09:20:21 -07:00
Tim Abbott
47465ea51a message_list: Fix missing date boundaries for newly sent messages.
When receiving the first new message of a new day, we were previously
not showing a date separator line before the message.

Fixes a regression introduced
in 00c7f7d42f.
2017-06-05 09:13:02 -07:00
Harshit Bansal
edfe595bf2 notifications: Fix incorrect narrowing behavior on Firefox.
On clicking a notification, the web app was not being narrowed to the
message topic on firefox. We now narrow to the message topic if a user
clicks on a notification. It was working correctly on Google Chrome.

Fixes: #5220.
2017-06-04 14:04:45 -07:00
Joshua Pan
28f2d33543 docs: Tweak developer discussions in chat-zulip-org doc. 2017-06-04 13:25:09 -07:00
Tim Abbott
772b51f938 docs: Update chat-zulip-org to discuss chat meetings. 2017-06-04 12:31:45 -07:00
Tim Abbott
bd81f66e01 settings: Fix ugly exclamation on default streams errors. 2017-06-04 10:42:41 -07:00
Tim Abbott
d2079cbb2e streams: Fix leaking private streams after last user is removed.
When the last user on a private stream is removed, the stream is no
longer possible to administer, and thus should be marked as
deactivated, so that default streams entries are removed and it no
longer appears in the UI as a non-administerable broken stream.
2017-06-04 10:40:41 -07:00
Tim Abbott
d21756c396 streams: Fix default streams list not updating on deactivation.
If you deactivated a default stream, we would correctly remove it from
the list of default streams in the organization.  However, we did not
call `send_event`, so browsers would still display it as a default
stream until the next reload.

This fixes that issue by calling do_remove_default_stream instead of
doing the database query directly.
2017-06-04 10:36:18 -07:00
Tim Abbott
eb25c6be87 user_info_popover: Fix incorrect icon for sending a private message.
Thanks to Nash Vail for noticing this issue.
2017-06-04 09:57:55 -07:00
Aditya Bansal
acefc67f2f lint: Start enforcing PEP-E261 by default in our linters.
In this commit we start to check for violations to PEP-E261 in our
codebase by default in our linters. Also we have introduced a
ignore list which has around 20 files still in violation to
PEP-E261 which we intend to clear up soon.
2017-06-04 09:18:23 -07:00
Aditya Bansal
5b2dec0845 pep8: Add compliance with rule E261 event_queue.py. 2017-06-04 09:18:23 -07:00
Aditya Bansal
4679da87c4 pep8: Add compliance with rule E261 decorator.py. 2017-06-04 09:18:22 -07:00
Aditya Bansal
a9e6106d54 pep8: Add compliance with rule E261 lint. 2017-06-04 09:18:22 -07:00
Aditya Bansal
0b746c5df4 pep8: Add compliance with rule E261 bots_test_lib.py. 2017-06-04 09:18:22 -07:00
Aditya Bansal
feb663ffb6 pep8: Add compliance with rule E261 backends.py. 2017-06-04 09:18:22 -07:00
Aditya Bansal
e28cafebaf pep8: Add compliance with rule E261 hellosign/view.py. 2017-06-04 09:18:18 -07:00
Aditya Bansal
90cdebb04a pep8: Add compliance with rule E261 bitbucket2/view.py. 2017-06-04 09:18:11 -07:00
Aditya Bansal
25bb21238f pep8: Add compliance with rule E261 test_unread.py. 2017-06-04 15:07:39 +05:30
Aditya Bansal
bf1e3a0125 pep8: Add compliance with rule E261 test_logging_handlers.py. 2017-06-04 15:07:26 +05:30
Aditya Bansal
4410b5889a pep8: Add compliance with rule E261 test_auth_backends.py. 2017-06-04 15:06:52 +05:30
Aditya Bansal
b99d62d337 pep8: Add compliance with rule E261 timeout.py. 2017-06-04 15:06:29 +05:30
Aditya Bansal
1be11cbb56 pep8: Add compliance with rule E261 replace-tarball-shebang. 2017-06-04 15:06:12 +05:30
Aditya Bansal
a9e0dbe085 pep8: Add compliance with rule E261 pretty_print.py. 2017-06-04 15:05:51 +05:30
Aditya Bansal
e3cf43399f pep8: Add compliance with rule E261 send.py. 2017-06-04 15:05:34 +05:30
Aditya Bansal
d2c215afde pep8: Add compliance with rule E261 zephyr_mirror_backend.py. 2017-06-04 15:05:22 +05:30
Aditya Bansal
cf9725836c pep8: Add compliance with rule E261 rss-bot. 2017-06-04 15:02:31 +05:30
Aditya Bansal
880314e45e pep8: Add compliance with rule E261 jabber_mirror_backend.py. 2017-06-04 15:01:39 +05:30
Aditya Bansal
02b855a389 pep8: Add compliance with rule E261 test-bots. 2017-06-04 15:00:58 +05:30
Aditya Bansal
8d06b5d9d9 pep8: Add compliance with rule E261 bot_lib.py. 2017-06-04 15:00:42 +05:30
Aditya Bansal
f0b1a6c8d2 pep8: Add compliance with rule E261 virtual_fs.py. 2017-06-04 14:58:37 +05:30
Tim Abbott
a3515b2f06 docs: Improve documentation on resource requirements. 2017-06-03 23:40:38 -07:00
Tim Abbott
e8166ee1b0 docs: Update installation docs for new RAM requirements.
This is a follow-up to #32.
2017-06-03 23:30:55 -07:00
Tim Abbott
b70986469c generate_secrets: Fix handling of missing trailing newlines.
When we added support for automatically adding new secrets in
generate_secrets.py, we failed to account for the possibility that a
human editor might have let the secrets file without a trailing
newline.

We address this by adding a leading newline before our new secret.

Fixes #5209.
2017-06-03 23:17:04 -07:00
Tommy Ip
8d6af030c0 bugdown: Fix modal_link.
The `data-toggle` property prevented the new style of overlay modals
from launching, and regardless, isn't a future-proof options for how
this should work.
2017-06-03 18:41:19 -07:00
Tim Abbott
cbce98edd6 Support informational overlays in hashchange system.
This helps the !modal_link links in our tutorial messages.

Fixes #5206.
2017-06-03 18:39:47 -07:00
Rishi Gupta
7527ac9a8c emails: Mark variables in non-HTML emails as HTML-safe.
Make sure 's, &s, and other characters are not HTML-escaped in subject
lines and plain-text emails.

Hack so that this isn't blocking the release of Zulip 1.6. A more robust way
to do this would be to have two different template Engines, one that renders
HTML, and one that doesn't.

Fixes #5088.
2017-06-03 16:04:06 -07:00
Tim Abbott
ba74d74dca lint: Fix incorrectly placed docstring. 2017-06-03 16:02:24 -07:00
Yago González
9602f73d05 lint: Add validation for the Swagger file. 2017-06-03 15:48:04 -07:00
Yago González
99b004942f lint: Explain the purpose of target_langs.
Tweaked by tabbott to be a longer docstring.
2017-06-03 15:48:00 -07:00
Yago González
7225b7bdf8 docs: Move Swagger file to static/swagger. 2017-06-03 15:45:15 -07:00
Aditya Bansal
5fc7e590bc travis: Cache the built emoji across builds in Travis CI.
Apparently, when we implemented the emoji cache for development, we
failed to properly register its directory for Travis CI.

Commit message rewritten by tabbott.
2017-06-03 15:30:55 -07:00
Aditya Bansal
e0d4eada4e travis: Fix zulip-npm-cache in Travis CI.
Apparently, when we migrated local development to use the
zulip-npm-cache structure, we failed to update the .travis.yml file
with the appropriate directory (and instead just uploaded a
node_modules symlink).
2017-06-03 15:30:53 -07:00
Aditya Bansal
23baaae980 travis: Stop deleting npm cache in production tests.
Now that we're not using the copy_modules functionality (basically
because including node_modules in production tarballs was a huge disk
sink), the production Zulip code isn't using `zulip-npm-cache` anyway.
And deleting that cache had a huge impact on the performance of the
development environment provisioning that we do as part of this suite.

Commit message rewritten by tabbott.
2017-06-03 15:29:08 -07:00
rht
940cf9db3b Run queue processors multithreaded in production if system memory <3.5GB.
While running queue processors multithreaded will limit the
performance available to very small systems, it's easy to fix that by
adding more RAM, and previously, Zulip didn't work on such systems at
all, so this is unambiguously an improvement there.

Fixes #32.
Fixes #34.

(Commit message expanded significantly by tabbott.)
2017-06-03 12:19:58 -07:00
Steve Howell
73afce23a0 Check for errors in process_read_message().
Report an error and early-exit if a stream message does
not have a stream_id for some reason.
2017-06-03 06:30:01 -06:00
Steve Howell
79acbcd1bf Refine error handling for stream_list.get_stream_li calls.
We avoid false warnings in get_stream_li and for updating
unread counts.  We also early-exit for A/D keys if there is
no current stream.
2017-06-03 06:16:45 -06:00
Tomasz Kolek
acd986d959 integrations: Fix custom topic of hellosign integration.
This fixes support for using custom topics in the HelloSign
integration.

With significant fixes and rebasing by Eeshan Garg.
2017-06-02 22:08:12 -07:00
Tim Abbott
907a059301 docs: update changelog with recent changes and 1.5.2 release. 2017-06-02 17:49:13 -07:00
Abhijeet Kaur
f320ff11f7 bots: Add tests for followup bot.
'followup' bot has different message handling behavior for
different messages.
For usual messages it calls 'send_message' function of
'BotHandlerApi' class.
For empty messages it calls 'send_reply' function of
'BotHandlerApi' class.
2017-06-02 17:24:41 -07:00
Abhijeet Kaur
72b877c7de bots: Add mock test for 'send_message' function in 'bots_test_lib' file.
Since few bots directly call 'send_message' function of
'BotHandlerApi' class instead of calling 'send_reply' function
first, add 'mock_test_send_message' to check for 'send_message'
function.

All test_<bot>.py files now need to specify which function the bot
will be sending the response to, for each particular message.

Make 'test_virtual_fs.py' and 'test_thesaurus.py' test files
consistent with other bots.
2017-06-02 17:24:41 -07:00
Cory Lynch
080a3b9286 Add test coverage for 'stream_sort.js'.
Added new file to test stream sort. Specifically,
it tests the `sort_group` function's ability to put
streams into the corect pinned/normal/dormant category,
filter them based on keyword, and sort alphabetically.
2017-06-02 18:13:33 -06:00
Eeshan Garg
32786802b0 docs: Document the release process for the Zulip API PyPI package. 2017-06-02 17:08:00 -07:00
Eeshan Garg
c065f23090 tools: Remove build-api-tarball. 2017-06-02 17:08:00 -07:00
Cory Lynch
76a497650b docs: Update feature tutorial for server_events_dispatch.js. 2017-06-02 16:51:46 -07:00
Cory Lynch
5d7828096e Split out server_events_dispatch.js from server_events.js. 2017-06-02 16:49:18 -07:00
Steve Howell
24d443a061 Have stream_list.get_stream_li() use stream_sidebar.get_row().
Given a stream id, we now find list items using the internal
data structures we created when we built the sidebar, rather than
using a jQuery selector.
2017-06-02 16:32:39 -07:00
Tim Abbott
d9b8da2483 docs: Fix emoji cache setup when not using provision.py.
There were 2 things wrong here:
(1) The new emoji cache directories weren't being created properly
(2) We weren't downloading the new emoji sprite sheets.

I think based on this experience, we should definitely invest in
moving more platforms to use provision.py.

Fixes #5160.
2017-06-02 15:21:46 -07:00
Tim Abbott
c37204c62a upgrade-zulip-stage-2: Remove an unused import. 2017-06-02 15:14:13 -07:00
Tim Abbott
1549f8773e portico: Always display org info when a server has only 1 realm.
Previously, we were incorrectly using the get_unique_open_realm
function to determine whether we're in the (common) single-realm
server case and should just display an org-info-enabled login form on
the homepage.

Now, we use a slightly different function extracted from
get_unique_open_realm that doesn't check whether the realm is
invite-only.

Fixes #4841.
2017-06-02 15:00:22 -07:00
Steve Howell
ed9eca90f2 node tests: Isolate timerender.js from i18n/jquery.
This makes the test run a lot faster, and it fixes
some leaky behavior where the test used to work only
when other tests ran before it.
2017-06-02 14:18:51 -07:00
Steve Howell
dc2be44daf refactor: Clean up timerender.render_date_span(). 2017-06-02 14:18:51 -07:00
Steve Howell
0aaa182fbe node test: Use zjquery to test stream_list.js.
We use zjquery now for testing stream_list.js, which runs faster
than the real jQuery and allows some test isolation.  The nature
of the test is basically the same, but we don't actually render
templates.  Instead of making assertions about the DOM, we are
now making assertions about how the stream lists get constructed
from other elements.
2017-06-02 14:11:11 -07:00
Steve Howell
ed49673555 stream_list: Use append() instead of appendTo().
Using append() is easier to unit test, and we avoid
creating a temporary jQuery object from the array
of sidebar rows.
2017-06-02 14:11:11 -07:00
Steve Howell
fdea8f9334 Create stream_list.initialize(). 2017-06-02 14:11:11 -07:00
Steve Howell
5dad7372f9 minor: Remove unneeded render in template tests.
(We have had ways to track partial templates for a while.)
2017-06-02 14:11:11 -07:00
Yago González
f878de8bd9 docs: Generalize the use of single quotes. 2017-06-02 14:08:57 -07:00
Yago González
08292f17a1 docs: Remove unnecesary quotes. 2017-06-02 14:08:57 -07:00
Yago González
6121a7ebd4 docs: Fix validation in the Swagger YAML file. 2017-06-02 14:08:57 -07:00
Tim Abbott
c250c8647d gear_menu: Fix traceback accessing i18n before it is initialized. 2017-06-02 14:03:56 -07:00
Tim Abbott
cecf7f1740 provision: Don't regenerate dev database unnecessarily.
This reuses the work we did some time ago to avoid regenerating the
test database unnecessarily.

In addition to being a nice convenience for developers (since any
accomulated test data is still available), this also saves about half
the time consumed in a no-op provision.

Fixes #5182.
2017-06-02 13:27:34 -07:00
Tim Abbott
a0ef2babab text_fixtures: Rename migration status file to have test in name.
This is preparation for making things clear as we move towards not
always rebuilding the test database in provision.
2017-06-02 13:27:34 -07:00
Tim Abbott
6d00da2b80 test_fixtures: Remove hardcoding of check_files status dir.
This is preparatory support for using this framework in provision as
well.
2017-06-02 13:27:34 -07:00
Tim Abbott
4da9383f2d dev_urls: Add comments documenting sections. 2017-06-02 12:44:32 -07:00
Joshua Pan
3905602da5 node tests: Test user timezone functions in people.js. 2017-06-02 06:30:40 -06:00
Joshua Pan
7be1576513 people.js: Refactor get_user_time function. 2017-06-02 06:30:40 -06:00
Tim Abbott
9e0749ad82 email-mirror-postfix: Fix mypy errors. 2017-06-01 22:51:26 -07:00
Eeshan Garg
e510c5d15a webhooks/pivotal: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
829491fde7 webhooks/papertrail: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
5d868b1612 webhooks/helloworld: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
6defd7f36e webhooks/pagerduty: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
36c5e8d11f webhooks/mention: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
ccd079b425 webhooks/solano: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
c3dda04270 webhooks/zapier: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
6e6c5c8fa6 webhooks/newrelic: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
88ed657412 webhooks/updown: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
a8e4abfb7c webhooks/teamcity: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
28a2166bd0 webhooks/transifex: Migrate docs to Markdown. 2017-06-01 22:16:12 -07:00
Eeshan Garg
624bab83a7 webhooks: Use append-topic.md for gosquared, greenhouse, hellosign. 2017-06-01 22:16:12 -07:00
Eeshan Garg
af88695c28 templates: Add macro for appending the topic to the webhook URL. 2017-06-01 22:16:10 -07:00
Steve Howell
1a4c8a598d tests: Add more coverage to narrow_state.js in test_stream(). 2017-06-01 22:14:11 -07:00
Steve Howell
8a39e67876 node tests: Extract narrow_state tests to new module. 2017-06-01 22:14:11 -07:00
Jeremy Bowman
2137aadda0 portico: Make the realm icon an img element.
The realm avatar icon on the login and registration pages was
being set as a background image, which could vanish in high
contrast mode in many browsers.  Converted it to an img tag and
verified that it is still styled correctly.  I think the empty
alt attribute (to remove it from the audio description) is
appropriate in this context, since the realm name and description
are already provided immediately afterwards in the page content.

Fixes #4889.
2017-06-01 22:07:43 -07:00
Umair Khan
bf2bc8d44b lint: Allow empty string in alt arg. 2017-06-01 22:07:43 -07:00
Rohitt Vashishtha
a4b76e78ac tools: Update clean-branches to clean review branches. 2017-06-01 21:55:33 -07:00
Rohitt Vashishtha
443e31e348 tools: Add script to see PRs as authors intended. 2017-06-01 21:55:08 -07:00
K.Kanakhin
47ec9fbbe2 email-mirror: Rewrite email mirror script on pure python.
The Zulip email mirror script called by postfix had performance/load
issues, because it spent so much time on startup/import due to use of
the Zulip virtualenv.

The script was rewritten using pure python (no Django) to improve
performance.
2017-06-01 21:50:49 -07:00
Joshua Pan
52518fbc29 node tests: Get people.js to 100% node coverage. 2017-06-01 20:27:58 -07:00
Tim Abbott
1f48fa2767 invite: Fix invite_by_admins_only to be enforced in backend.
This is CVE-2017-0896.

Apparently, this setting never actually was wired up to anything other
than hiding the UI widget.

Huge thanks to Ibram Marzouk from the HackerOne community for finding
this security bug.
2017-06-01 17:24:29 -07:00
Rohitt Vashishtha
db9918f3d6 bots: Move contrib_bots to api/bots*.
This will make it convenient to include these bots in Zulip API
releases on pypi.

Fix #5009.
2017-06-01 12:31:54 -07:00
Steve Howell
d36e528fdd minor: Fix comment in unread.get_counts(). 2017-06-01 13:28:44 -06:00
Saket Kumar
5093adf3f5 Update reading-list.md
Adds some course for React Native and Java Beginners.
2017-06-01 09:35:18 -06:00
Akhil
64f2b51496 typeahead: Add pm_conversations module.
In pm_conversations.js, added function to make a user a PM partner and
another function to check if a user is a PM partner. A PM partner is
someone with whom the user has been in a PM with.
2017-06-01 08:05:37 +00:00
Akhil
f04da3d52e typeahead: Add recent_senders module.
In recent_senders module, added a data structure to hold timestamps of
users' latest message in a topic. Also added a function to compare 2
users based on above timestamp. Added a function to process messages for
the data structure and a call in add_message_metadata. Also added node
tests for insertion of data into recent_senders.senders.
2017-06-01 08:05:37 +00:00
Tim Abbott
73f8653da6 test_messages: Increase time allowed for bulk send.
This fixes an occasional test flake we've been seeing recently.
2017-06-01 00:00:36 -07:00
Tim Abbott
be814b940d setup_venv: Pin a version of setuptools for creating venvs.
This works around a bad recent setuptools release:

https://github.com/pypa/setuptools/issues/1042
2017-05-31 23:58:24 -07:00
Cory Lynch
aa3ef439eb Add coverage for 'typing' dispatch. 2017-05-31 18:07:25 -07:00
Cory Lynch
cd3f9354c0 Add coverage for 'delete_message' dispatch. 2017-05-31 18:07:25 -07:00
Cory Lynch
4449aba471 Add coverage for 'realm_domains' dispatch. 2017-05-31 18:07:25 -07:00
Cory Lynch
93a8ae852e Add coverage for 'reaction' dispatch. 2017-05-31 18:07:25 -07:00
Cory Lynch
93dc288e5e Add coverage for 'hotspots' dispatch. 2017-05-31 18:07:25 -07:00
Harshit Bansal
8aa2949b4d settings: Fix traceback on opening emoji settings tab.
Realm emojis uploaded before the migration to store the emoji author
information was done don't have any author information. Such emojis
if listed on the settings page caused a traceback.

Fixes: #5133.
2017-05-31 17:17:51 -07:00
Aditya Bansal
a0faf3364a pep8: Add compliance with rule E261 test_reactions.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
feffbb963b pep8: Add compliance with rule E261 run-mypy. 2017-05-31 17:07:15 -07:00
Aditya Bansal
7bb669ccb4 pep8: Add compliance with rule E261 test_email_mirror.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
15ea059aad pep8: Add compliance with rule E261 makemessages.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
5b0b8fd8bb pep8: Add compliance with rule E261 emoji_setup_utils.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
ee369ceb0c pep8: Add compliance with rule E261 scripts/lib/email-mirror-postfix. 2017-05-31 17:07:15 -07:00
Aditya Bansal
aa433f4342 pep8: Add compliance with rule E261 check_send_receive_time. 2017-05-31 17:07:15 -07:00
Aditya Bansal
9814bd77cc pep8: Add compliance with rule E261 google/google-calendar. 2017-05-31 17:07:15 -07:00
Aditya Bansal
42b0680ab2 pep8: Add compliance with rule E261 populate_analytics_db.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
bcc247a5b1 pep8: Add compliance with rule E261 zilencer/urls.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
717e5ae393 pep8: Add compliance with rule E261 commands/create_realm.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
8680c87f56 pep8: Add compliance with rule E261 zerver/lib/push_notifications.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
be66369b72 pep8: Add compliance with rule E261 tools/js-dep-visualizer.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
807fee68d6 pep8: Add compliance with rule E261 nagios/check-rabbitmq-consumers. 2017-05-31 17:07:15 -07:00
Aditya Bansal
dee726f234 pep8: Add compliance with rule E261 scripts/lib/pythonrc.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
5989c88545 pep8: Make compliant zulip-ec2-configure-interfaces with rule E261. 2017-05-31 17:07:15 -07:00
Aditya Bansal
6b8e85e065 pep8: Make compliant check_zephyr_mirror with rule E261. 2017-05-31 17:07:15 -07:00
Aditya Bansal
49ae51f23a pep8: Make compliant check_user_zephyr_mirror_liveness with rule E261. 2017-05-31 17:07:15 -07:00
Aditya Bansal
6d0927ed0b pep8: Add compliance with rule E261 to check_personal_zephyr_mirrors. 2017-05-31 17:07:15 -07:00
Aditya Bansal
cc9e08bf87 pep8: Add compliance with rule E261 to bots/check-mirroring. 2017-05-31 17:07:15 -07:00
Aditya Bansal
3c50019001 pep8: Add compliance with rule E261 to api/integrations/rss/rss-bot. 2017-05-31 17:07:15 -07:00
Aditya Bansal
5b6a21c100 pep8: Add compliance with rule E261 to api/examples/upload-file. 2017-05-31 17:07:15 -07:00
Aditya Bansal
30dfb54c65 pep8: Add compliance with rule E261 to analytics/views.py. 2017-05-31 17:07:15 -07:00
Aditya Bansal
061cb9ae44 pep8: Add compliance with rule E261 to analytics/tests/test_views.py. 2017-05-31 17:07:15 -07:00
Cynthia Lin
09419aa027 hotkeys: Allow n key to work on PMs.
Fixes #4885
2017-05-31 18:00:57 -06:00
Joshua Pan
fd57fcbc1c node tests: Add coverage for blueslip errors in people.js.
This covers all blueslip errors and warnings
in people.js. These do not need to be tested
to rigorously and just need to be covered to
get people.js to 100% coverage.
2017-05-31 16:04:49 -06:00
Steve Howell
cc81b7892d Add process_visible() call to maybe_select_closest().
This fixes a regression where we removed a call to
unread_ops.process_visible() inside of stream_list.js.  Now
we call it from within narrow.activate() in the the
maybe_select_closest() callback.
2017-05-31 12:40:57 -06:00
Pweaver (Paul Weaver)
2efecd4809 webpack: Fix webpack-dev-server to not inline serve bad sockjs url.
Fixes #5118.
2017-05-31 09:31:29 -07:00
Umair Khan
5d794d08dd test_bulk_message_fetching: Add debug code.
This test fails on self.assertTrue(delay < 0.001 * num_ids, error_msg)
randomly. This commit adds debug code to see what the real values of
paramters are.
2017-05-31 09:27:30 -07:00
Harshit Bansal
fc0fb66d28 emoji: Fix realm emoji not appearing in settings page when reopened.
When the emoji settings page was reopened after uploading a realm
emoji without doing a page refresh, the uploaded emoji disappeared
from the emoji list. This was so because the emoji settings page uses
`page_params.realm_emoji` to render the emojis which was not updated
when a emoji was added.

Fixes: #5130.
2017-05-31 09:12:45 -07:00
Steve Howell
e1f5a4e0bb Add test_expand_and_update_private_messages(). 2017-05-31 09:10:43 -07:00
Steve Howell
22dfb9f09d Add test_update_dom_with_unread_counts(). 2017-05-31 09:10:43 -07:00
Steve Howell
0b0c57bbe0 zjquery: Throw Error() object to get tracebacks.
If you throw a raw string in node, you don't get a traceback.
2017-05-31 09:10:43 -07:00
Jeremy Bowman
1dae2af7b0 Fix ARIA markup for settings menu
The settings dropdown was marked as having the "menu" ARIA role,
but contained no items with the "menuitem" role.  I assigned this
role to the focusable link elements, and gave the intervening "li"
elements (and other "li" elements used as separators and such)
the "presentation" role to allow those to be gracefully ignored
when appropriate.  Some of the links previously had the "button"
role, which I think was a holdover from a previous UI layout.

Fixes #5000.
2017-05-30 23:08:12 -07:00
Cynthia Lin
b81e7ad51f hotkeys: Fix arrow key navigation in Streams modal.
Previously, one could not move past unsubscribed streams in the
Subscribed tab.

Fixes #5066.
2017-05-30 22:51:35 -07:00
Umair Khan
6ee08e0602 casper: Fix waiting condition in message deletion tests.
We now specifically wait for the length to decrease by one. This seems
like a more deterministic condition to wait on.

Previously we were waiting till the id of the deleted message remained
visible; intuitively, this should have worked but it seems that there
is some race condition that was causing the test to fail sporadically.
2017-05-30 22:49:59 -07:00
Pweaver (Paul Weaver)
eb1a22a1d2 webpack: Fix webpack-dev-server urls for external resources.
This fixes issues some users found using the remote development environment.
2017-05-30 22:38:25 -07:00
Eeshan Garg
fc6125ec2e api/setup.py: Upgrade the version to 0.3.1.
Apparently, PyPI is very strict about package file names. Once you
upload files for 0.3.0, and only wish to make minor changes and
re-release it as the same version, it doesn't let you and complains
about identical file names.
2017-05-30 22:25:14 -07:00
Eeshan Garg
ea131936d6 api/setup.py: Upgrade to Beta and update homepage URL. 2017-05-30 22:25:14 -07:00
Eeshan Garg
b309c403e0 webhooks/gitlab: Support Merge Request Hook reopen event.
Fixes #4795.
2017-05-30 22:11:37 -07:00
Steve Howell
4ec1260b41 reactions.js: Have an initialize() function. 2017-05-30 21:43:18 -07:00
Steve Howell
6149111b5e Add test_error_handling() for reactions.js. 2017-05-30 21:43:18 -07:00
Steve Howell
b0b647c9e5 Add more code to test_add_and_remove_reaction().
This increases our line coverage a bit.
2017-05-30 21:43:18 -07:00
Steve Howell
e7345bdd7f Improve error reporting in maybe_activate_stream_item.
This change should lead to clearer tracebacks when our
assumption about the stream list's list items get
violated, and we also short circuit some code in the
caller that tries to scroll to the active stream.
2017-05-30 21:26:55 -07:00
Steve Howell
561fba65d2 Remove spurious call to unread_ops.process_visible().
In stream_list.js we have some code to handle narrow activations,
and we were calling unread_ops.process_visible() only for
stream activations, not for PM-related activations, etc., so
our approach was inconsistent.

It also turns out that the call is redundant, since we call
unread_ops.process_visible() when the message pane scrolls as
part of updating the content.

Ideally, we want a more rigorous approach where we make this
call precisely when the new messages become visible to the user,
but the purpose of this fix is to de-clutter the stream_list
logic.
2017-05-30 21:26:55 -07:00
Eeshan Garg
2e81fdd319 api.html: Recommend pip install for installing API bindings.
We have an updated PyPI package now for our API bindings, so we
now recommend `pip install` rather than providing a download link
to the package.
2017-05-30 21:21:06 -07:00
Steve Howell
b559364614 Use zjquery to test pm_list.js.
We now stub templates.render() to see what data gets passed in
to the template, rather than using jQuery to inspect the DOM that
gets created.  This changes the nature of the test to be less about
integration with the templating layer and more about how we pass
data into the template.

To compensate, we add more assertions to the relevant test
in templates.js.
2017-05-30 20:46:30 -07:00
Tim Abbott
e321891f17 test-all: Don't run SVG optimizer by default. 2017-05-30 11:19:53 -07:00
Cynthia Lin
0600e1eb30 tools: Add optimize-svg tool for checking for unoptimized SVG files. 2017-05-30 11:15:56 -07:00
Cynthia Lin
76537665b9 integrations: Optimize SVG graphics. 2017-05-30 11:15:56 -07:00
Cynthia Lin
26afd4c162 integrations: Modify styling to emphasize label text. 2017-05-30 11:15:56 -07:00
Umair Khan
71f97b7bcb testing: Invalidate cache before counting queries.
To get accurate count of the queries, we should make sure that
caches don't come into play. If we count queries while caches are
filled, we will get a lower count. Caches are not supposed to be
persistent, so our test can also fail if cache is invalidated
during the course of the unit test.

This commit solves the problem with Stream cache. This cache comes
into play when we use `get_stream` function. If cache is valid,
we will not issue queries to Stream and Recipient table. I think
the problem was one of those rare occasions when the Stream cache
got invalidated during the course of the test, due to which query
count was increased by 2. After this commit, we intentially invalidate
the Stream cache.
2017-05-30 17:28:41 +05:00
K.Kanakhin
2434f2d96c messages: Add support for admins deleting messages.
This makes it possible for Zulip administrators to delete messages.
This is primarily intended for use in deleting early test messages,
but it can solve other problems as well.

Later we'll want to play with the permissions model for this, but for
now, the goal is just to integrate the feature.

Note that it saves the deleted messages for some time using the same
approach as Zulip's message retention policy feature.

Fixes #135.
2017-05-29 21:59:38 -07:00
neiljp
9b13b19006 docs: Add ')' and correct reference to step number in bots guide. 2017-05-29 20:52:23 -07:00
Abhijeet Kaur
4a531ac203 Updates get_help() function in 'virtual_fs' bot.
Update example commands from calling by keyword 'fs'
(As was done previously) to calling by at-mention of
the bot.
Updates '/contrib_bots/bots/virtual_fs/virtual_fs.py' by
correcting instructions on how to call 'virtual_fs' bot.
2017-05-29 20:44:13 -07:00
Abhijeet Kaur
9f17bded92 Fix minor errors in bots-guide. 2017-05-29 20:41:15 -07:00
neiljp
643d70eae1 contrib_bots: Add check_expected_responses() test helper and use it.
This further simplifies the logic for testing a contrib_bots bot to
require very little code per test in the common case.
2017-05-29 20:39:27 -07:00
Krzysztof Krzysztof
695c71d2cc bots: Add weather reporting bot. 2017-05-29 20:33:16 -07:00
Harshit Bansal
7126f6f30c settings: Allow either admin or realm emoji author to delete it.
If a realm is configured to allow any user to upload a realm emoji
then that user should also be allowed to delete the emoji in case
he feels it doesn't look good or if he uploaded a wrong emoji file.
This commit tweaks the realm emoji settings UI to allow an user who
uploaded an emoji to delete it.

Fixes: #4761.
2017-05-29 20:21:26 -07:00
Harshit Bansal
298e23b447 realm_emoji.py: Allow an user to delete an emoji uploaded by them.
If a realm is configured to allow any user to upload an emoji,
then, an emoji author must be allowed to delete an emoji uploaded
by them.
2017-05-29 20:21:25 -07:00
Steve Howell
879abd6290 Add coverage for update_existing_reaction(). 2017-05-29 20:10:53 -07:00
Steve Howell
1ae66cda6f Increase test coverage for insert_new_reaction. 2017-05-29 20:10:53 -07:00
Steve Howell
80920438a5 Add coverage for get_emojis_used_by_user_for_message_id. 2017-05-29 20:10:53 -07:00
Eeshan Garg
99c2e1875d api: Increase the version from 0.2.5 to 0.3.0. 2017-05-29 20:09:59 -07:00
Eeshan Garg
debe9fa9dc api: If there is no $HOME, assume .zuliprc doesn't exist. 2017-05-29 20:09:57 -07:00
Steve Howell
ecbbc8788a Move code from reactions -> emoji_picker.
This moves all the code dealing with emoji_picker
navigation and click/enter events to emoji_picker.js.

Some of the code still delegates back to reactions.js
in some way.

The navigate() code really does nothing reaction-specific,
nor does filter_emojis(), nor do some of their helpers.

This was mostly moving code, but I also did some
s/reaction// or s/reaction/emoji/ in names.
2017-05-29 17:10:05 -06:00
Steve Howell
3654406f17 Simplify/rename code to choose reaction in emoji picker.
We now call the function toggle_selected_emoji(), and it
is simpler in these ways:

    * We get the selected emoji more directly.
    * We reuse code in toggle_emoji_reaction().
2017-05-29 17:10:05 -06:00
Steve Howell
ed2ceb49cb Use toggle_emoji_reaction for "+" hotkey.
This is a more direct codepath when we know which emoji
we want to toggle.
2017-05-29 17:10:05 -06:00
Steve Howell
1ee757a237 Use toggle_emoji_reaction() in the emoji picker.
If we know the name of the emoji you need to toggle,
we can toggle_emoji_reaction(), which is less complex
than toggle_reaction().
2017-05-29 17:10:04 -06:00
Steve Howell
805c99ae27 Add hide_emoji_popover() to toggle_emoji_reaction().
This change sets us up to de-duplicate some code.  It
changes behavior for the edge case situation where
you had the reaction menu open but then decide to
click on one of the existing reactions.  This change
closes the emoji popover, which is probably the
correct behavior.
2017-05-29 17:10:04 -06:00
Steve Howell
63d0711c4b Rename message_reaction_on_click() to toggle_emoji_reaction().
This prepares us to de-duplicate some code.
2017-05-29 17:10:04 -06:00
vaibhav
9cf9837f12 webhooks: Add outgoing webhook bot user to development database. 2017-05-29 16:01:23 -07:00
Tim Abbott
4acc89d379 help: Document the : hotkey for choosing reactions. 2017-05-29 15:43:55 -07:00
Tim Abbott
7b152bf0ad help: Clarify discussion of the emoji reactions picker.
The word "menu" was kinda confusing here.

Follow-up to #4547.
2017-05-29 15:43:44 -07:00
Daniel Lau
3037be9bc0 help: Document how to navigate the emoji reactions picker.
Fixes #4547.
2017-05-29 15:43:07 -07:00
Tim Abbott
4040cadf7d coverage: Omit some test runner files from coverage.
These files are part of the test runner and can't realisitically have
test coverage due to being imported before coverage in the setup
sequence.
2017-05-29 15:30:49 -07:00
Tim Abbott
4893779001 test_events: Avoid coverage errors in LogEventsTest. 2017-05-29 15:26:33 -07:00
Maxim Averin
a4c3f571db Switch change_tos_version to use RealmAuditLog. 2017-05-29 15:24:01 -07:00
Maxim Averin
685fb16c39 Switch change_full_name to use RealmAuditLog.
This requires adding an `acting_user` parameter to the
`do_change_bot_owner` function.
2017-05-29 15:22:08 -07:00
Tim Abbott
ce26f0e086 integrations: Remove legacy basecamp integration.
Now that we have the webhook integration, there's no reason to
maintain the pre-webhook version.
2017-05-29 15:10:59 -07:00
Steve Howell
49e3ee36c4 Add tests for reactions.remove_reaction(). 2017-05-29 14:59:52 -07:00
Steve Howell
affff8ac82 Extract reactions.set_reaction_count. 2017-05-29 14:59:52 -07:00
Steve Howell
1747223c35 reactions: Refactor remove_reaction().
* Add whitespace/comments.
    * Use find_reaction() helper.
    * Handle full-removal earlier in block.
    * Sequence operations in a more organized way.
2017-05-29 14:59:52 -07:00
Steve Howell
5c405f7048 reactions: Refactor add_reaction().
This commit splits out some helper methods to make it easier
to test:

    get_reaction_section
    find_reaction
    get_add_reaction_button
    update_existing_reaction
    insert_new_reaction
2017-05-29 14:59:52 -07:00
Rohitt Vashishtha
2d73e03e37 ui-refactor: Rename modals.js to overlays.js.
Fixed #4702.
2017-05-29 11:24:46 -07:00
Steve Howell
1f4e1ece3a Fix flaky time-based test.
For testing waiting period thresholds, we need to
explicitly set date_joined for Hamlet to be now.
2017-05-29 11:54:06 -06:00
David
43e76816ff message view: Recipient bar date stamp shows older years.
timerender.js render_now() will always include older
years when rendering the date stamp on the recipient bar
and the date rows above messages.

Fixes #4843.
2017-05-29 08:54:06 -07:00
David
fcf97660db testing-coverage: add node tests for timerender.js.
Initial set of tests for the timerender.js module.

Fixes #4819.
2017-05-29 08:51:28 -07:00
David
ea3c994186 refactoring: timerender.js render_now() returns an object.
The render_now() function in timerender.js will now return
an object instead of an array, which is then passed to the
functions render_date_span() and update_timestamps().
This should increase readability and extensibility.

Fixes #4820.
2017-05-29 08:51:24 -07:00
Tim Abbott
5ffdce9aab test-js-with-node: Set timezone to UTC for tests. 2017-05-29 08:47:26 -07:00
Steve Howell
5f48b51b60 provision: Add cd /srv/zulip to profile.
I didn't bump the provision version on this change, as it
won't break anything if somebody fails to make this change.
2017-05-29 08:40:49 -07:00
Cory Lynch
c95abd4618 Replace broken aria-labelledby with aria-label in help modal.
Fixes #4921.
2017-05-28 22:49:16 -07:00
Cory Lynch
30e54a94f2 html: Add aria-labels for search bars for accessibility.
Added an attribute which can be read by assistive technology.

Fixes #4996.
2017-05-28 22:49:00 -07:00
derAnfaenger
735aa9f2c6 Rename misleading 'system-docs' reference. 2017-05-28 22:21:13 -07:00
derAnfaenger
c0f0dabec6 Rename misleading 'code-docs' reference. 2017-05-28 22:21:13 -07:00
derAnfaenger
7f6b6fae26 Rename misleading 'tutorial-docs' reference. 2017-05-28 22:21:13 -07:00
derAnfaenger
f6c59a483c docs: Rename misleading 'dev-install-docs' reference. 2017-05-28 22:21:13 -07:00
derAnfaenger
54a618b597 docs: Rename misleading 'prod-install-docs' reference. 2017-05-28 22:21:13 -07:00
derAnfaenger
9c0ba87b5e docs: Rename misleading 'user-docs' reference. 2017-05-28 22:21:13 -07:00
Ron Shafii
8cc1f13d24 test: Add test_notify_realm_of_new_user. 2017-05-28 19:14:52 -07:00
Eeshan Garg
44ec27c122 webhooks/gosquared: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
e5484f1bf5 webhooks/ifttt: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
846e560bfd webhooks/hellosign: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
372d6a2aa6 webhooks/heroku: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
2d25b6581e webhooks/greenhouse: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
dd5ce955bd webhooks/delighted: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
074e3d7401 webhooks/crashlytics: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
14ce3a94db webhooks/codeship: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
6111b56753 webhooks/circleci: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Eeshan Garg
1c50a85601 webhooks/basecamp: Migrate docs to Markdown. 2017-05-28 18:44:00 -07:00
Rohitt Vashishtha
442537ebb8 overlays: Rename hashchange.exit_modal() to exit_overlay. 2017-05-28 18:40:54 -07:00
Ethan Estrada
91e6f00d57 Test that log_event auto creates missing log dir. 2017-05-28 18:24:00 -07:00
Ethan Estrada
a11c578d57 Test for early return when "LOG_EVENT_DIR" is None. 2017-05-28 18:21:50 -07:00
Tim Abbott
9d7e6b1b48 events: Fix race with realm_waiting_period_threshold changes.
The can_create_streams property changed some time ago to depend on 2
different properties of Realm, causing occasional test failures.
2017-05-28 18:21:50 -07:00
Krzysztof Krzysztof
089e5896a6 bots: Add Youtube Bot.
This sends the first video from youtube search results as a reply.
2017-05-28 18:13:59 -07:00
neiljp
ac7c5f51e2 contrib_bots: Add tests for xkcd bot. 2017-05-28 17:59:54 -07:00
Theodore Chen
fef15a7bf4 test-bots: Add support for testing a single bot. 2017-05-28 17:52:51 -07:00
Ian Winter
a277164ad6 docs: Add new functions to bots-guide.md.
This commit reflects the recent changes being
done to the `contrib_bots` API and introduces
the new methods in the docs.
2017-05-28 17:46:25 -07:00
Pweaver (Paul Weaver)
2a394708ba Modify front-end-build-process.md to reflect use of typescript. 2017-05-28 17:32:49 -07:00
Pweaver (Paul Weaver)
bbb3aad611 Add typescript support to asset compilation. 2017-05-28 17:28:28 -07:00
Abhijeet Kaur
601d018367 testsuite: Add tests for wikipedia bot in contrib_bots.
Add test file 'Test_wikipedia.py'.

Since wikipedia links for the same query may different according
to relevance. This test will also be written by mocking HTTP
traffic. But this can work for now.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
9f861d6d67 testsuite: Add tests for virtual_fs bot in contrib_bots.
Add test file 'test_virtual_fs.py'.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
02256f79e4 bots: Add a new command 'sample_conversation' in virtual_fs bot.
The previous test function in virtual_Bot made use of another function
called a 'sample_conversation' which had stateful example conversation
with virtual_fs bot.

The function sample_conversation is really useful, so made it accessible
to the users too.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
469e2acf4d bots: Remove already present test function in virtual_fs bot.
Remove test function for virtual_fs bot from virtual_fs.py file.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
b3dddbe75f bots: Modify 'virtual_fs' bot to respond with help message on bot mention.
Earlier, if virtual_fs bot is called without any argument, then the
bot returns nothing.
Now, virtual_fs bot replies with help message on how the user can
call this bot.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
d4443b05fb testsuite: Add tests for thesaurus bot in contrib_bots.
Add test file 'test_thesaurus.py'.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
af4750799c bots: Remove unwanted spaces from 'help_message' in thesaurus bot.
Remove unwanted spaces from the file contrib_bots/bots/thesaurus/thesaurus.py,
these spaces were being stripped while being written to
zulip console.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
dbe5a65378 testsuite: Add tests for help bot in contrib_bots.
Add test file 'test_help.py'.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
707cc6ec2c bots: Remove unnecessary split() function from help bot.
Remove unnecessary split() function from the file
contrib_bots/bots/help/help.py and replaced it with equivalent
simpler string.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
afbaa30e4b testsuite: Add tests for helloworld bot in contrib_bots.
Add test file 'test_helloworld.py'.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
74acc53a8a testsuite: Add tests for encrypt bot in contrib_bots.
Remove previous unittest file for encrypt bot. Add new
test file which is in accordance with the test-suite famework
developed for contrib_bots.
2017-05-28 17:12:11 -07:00
Abhijeet Kaur
d2e359e05c testsuite: Add tests for converter bot in contrib_bots.
Remove previous unittest file for converter bot. Add new
test file which is in accordance with the test-suite famework
developed for contrib_bots.

Since 'coverter' folder is now a package (addition of __init__.py),
modify converter.py to import utils.py from the same package.
2017-05-28 17:12:11 -07:00
Steve Howell
cb0527397e Add tests for reactions.add_reaction(). 2017-05-28 16:58:32 -07:00
Steve Howell
8d7cd2e3af Add tests for reactions.message_reaction_on_click(). 2017-05-28 16:58:32 -07:00
Tejas Kasetty
f48df30c20 typeahead: Move prefix_sort helper to util.js.
This will allow us to call this function from the reactions code as
well.
2017-05-27 09:37:57 -07:00
Tim Abbott
4a8eb8775f docs: Fix a link on accessibility page. 2017-05-26 21:02:47 -07:00
Tim Abbott
9b8641d9eb lint: Add iOS to list of valid weird capitalizations. 2017-05-26 20:59:32 -07:00
Tim Abbott
c864bb59c6 apps: Fix typo in template syntax. 2017-05-26 19:06:20 -07:00
umkay
d9b23b39d3 mypy: Fix strict-optional in analytics. 2017-05-26 15:39:39 -07:00
Umair Khan
7f43ec05f2 lint: Add rule to check alt arg for translation. 2017-05-26 15:28:46 -07:00
Umair Khan
ad5780c03e lint: Mark alt argument for translation. 2017-05-26 15:28:46 -07:00
Tim Abbott
9b050f4cac bots: Remove legacy bots/ directory. 2017-05-26 15:21:30 -07:00
Tim Abbott
c5bc1265f3 bots: Move log2zulip into api/integrations. 2017-05-26 15:15:56 -07:00
Tim Abbott
55f69c677a puppet: Remove obsolete zuliprc.nagios file.
This hasn't done anything for years.
2017-05-26 15:14:12 -07:00
Reid Barton
ccb4c5c26f bots: Move zephyr-related files to api/integrations/zephyr/. 2017-05-26 15:07:02 -07:00
Reid Barton
2f21290407 bots: Move IRC and Jabber mirror scripts to api/integrations.
This is part of cleaning out the old bots/ top level directory.
2017-05-26 15:04:55 -07:00
rht
a1f82e02d6 python: Replace os.system with subprocess.call.
Generally, we avoid os.system, since it shells out and thus can be
a cause of security issues.
2017-05-26 15:03:16 -07:00
Sarah
bb329b4020 zerver/lib/events: Refactor using UserProfile prop_types and notifications
Refactor fetch_initial_state_data to use the UserProfile.property_types
and notifications dictionaries.
2017-05-26 14:55:54 -07:00
derAnfaenger
024101be6b bots: Add mypy annotations for bots framework.
This commit adds mypy annotations for both the main
bots and the bots testing runner. It involves a change
to the BotHandlerApi send_message and update_message
funtions, which is compatible with every bot.

Tweaked by tabbott to use more expressive annotations.
2017-05-26 10:25:06 -07:00
Tim Abbott
c12023840d contrib_bots: Fix python 3 lint errors. 2017-05-26 10:18:40 -07:00
Nathan Miller
2311e169ec mypy: Various strict-optional fixes in zerver. 2017-05-26 10:10:20 -07:00
Reid Barton
004ff1ae4d bots: Remove githook-post-receive link.
Based on commits cdedb8593 and 58a8934a8 it seems to be unused.
2017-05-25 18:05:35 -07:00
Tim Abbott
f5373c46f2 lint: Fix trailing newlines in outgoing webhook tests. 2017-05-25 16:28:11 -07:00
Reid Barton
461856dd56 rss-bot: Add --unwrap, --math options.
These are for processing arXiv API results.
2017-05-25 16:24:07 -07:00
Tim Abbott
8e978df957 mypy: Fix missing import from recent mypy merge. 2017-05-25 16:22:19 -07:00
Pweaver (Paul Weaver)
cb311e99d8 Change backend tests to use a webpack stats stub file. 2017-05-25 16:15:32 -07:00
Pweaver (Paul Weaver)
de98dd127d Remove webpack dependency from tools/minify-js. 2017-05-25 16:15:32 -07:00
Pweaver (Paul Weaver)
fb0d2d6a8e webpack: Move assets to a separate JSON file so we can process in python. 2017-05-25 16:15:32 -07:00
Mehanig
2d5097868a webpack: Skip compilation for minified 3rd party libs. 2017-05-25 16:15:32 -07:00
Jeremy Bowman
5436f872f7 Provide alt text for validation check mark
The check mark which appears for valid input in assorted forms
(such as login and registration) didn't have alternative text
for better accessibility.  Added "Valid" as the alt text in all
places it's used.

Fixes #4876.
2017-05-25 16:06:47 -07:00
Ethan
d4d689532d mypy: serve_local return type to FileResponse. 2017-05-25 15:41:52 -07:00
Ethan
d2e72b0082 mypy: correct process response type. 2017-05-25 15:41:51 -07:00
Ethan
b6e7e36c86 mypy: correct from int to str in rate limiting. 2017-05-25 15:41:49 -07:00
Ethan
d1bd19a1b8 mypy: correct user_passes_test first argument. 2017-05-25 15:41:48 -07:00
Ethan
c284d913cc mypy: request.body is bytes, should be str. 2017-05-25 15:41:46 -07:00
Ethan
1477a9102d mypy: Fix return annotation; json_method_not_allowed. 2017-05-25 15:41:44 -07:00
Tim Abbott
944935dbe3 docs: Update Git tips blog post in reading list. 2017-05-25 15:29:37 -07:00
Elliott Jin
4907f24603 bots: Add additional service bot tests. 2017-05-25 15:00:51 -07:00
Elliott Jin
af49a23013 bots: Generalize service bot tests to also test embedded bots. 2017-05-25 15:00:51 -07:00
Elliott Jin
cd8c77bf91 bots: Clean up order and naming of service bot tests. 2017-05-25 15:00:51 -07:00
Elliott Jin
49adeee8c8 bots: Move service bot tests into separate file. 2017-05-25 15:00:51 -07:00
Elliott Jin
8b98b79646 bots: Generate queue events for embedded bots. 2017-05-25 15:00:51 -07:00
Elliott Jin
0ec9e54954 bots: Add queue and QueueProcessingWorker for embedded bots. 2017-05-25 15:00:51 -07:00
Elliott Jin
f7b124145b bots: Add __init__.py so bot modules can be imported. 2017-05-25 15:00:51 -07:00
Elliott Jin
d0c0031b0b bots: Add comments about embedded bots to Service model. 2017-05-25 15:00:51 -07:00
Elliott Jin
824b315284 bots: Introduce "service_bot" concept in UserProfile model. 2017-05-25 15:00:51 -07:00
Elliott Jin
120b7b4caf bots: Add bot_type for embedded bots in UserProfile model. 2017-05-25 15:00:51 -07:00
Tim Abbott
33c8488cf6 deps: Update PROVISION_VERSION for webpack upgrade. 2017-05-25 14:23:41 -07:00
Sarah
e304c47970 settings_org: Split out separate forms for orgs settings/permissions/auth.
Steve Howell also contributed to this PR.
2017-05-25 14:18:04 -07:00
Jeremy Bowman
7053103896 Fix registration email field label association
The label element for the registration form's email field was
missing a "for" attribute to link it to the input field.  Added
the missing attribute.

Fixes #4896.
2017-05-25 13:36:27 -07:00
Reid Barton
96dff66743 katek: Make tex errors gray.
Red is too visually loud for a medium where tex errors are not fatal
(readers will be still able to understand the tex source).
2017-05-25 10:57:10 -07:00
Reid Barton
f1eb8545b8 katex: Fix line height of inline math.
24cbd6113 changed the line height of katex HTML to avoid overlapping
lines in wrapped math displays. But the change also applied to inline
math, resulting in large vertical gaps in a multi-line paragraph
containing inline math elements.
2017-05-25 10:49:56 -07:00
Jeremy Bowman
64721abac3 Correctly associate bot name field label
The label element for the bot name editing field was trying to use
a "for" attribute to link it to the input field, but the field had
no ID for it to associate with.  Added the ID value which it
was trying to use.

Fixes #4999.
2017-05-25 10:46:01 -07:00
Yago González
d7ecb252df node tests: Add tests for colorspace.js. 2017-05-25 10:09:39 -07:00
Yago González
f25c16b573 node tests: Add coverage for get_all_bots_for_current_user. 2017-05-25 09:54:05 -07:00
Yago González
115b2f6b6b node tests: Fix indentation. 2017-05-25 09:54:05 -07:00
Elliott Jin
5b4d2832fc bots: Add management command for making outgoing webhook bot. 2017-05-25 09:45:54 -07:00
umkay
9ab0a8be6a mypy: Fix strict optional in zerver/views. 2017-05-25 09:30:41 -07:00
Yago González
55b4a3792d lint: Fix violation in the GitHub webhook view. 2017-05-24 22:09:14 -07:00
umkay
f4617d0408 mypy: Fix a few webhook tests to work with strict-optional. 2017-05-24 20:31:21 -07:00
Reid Barton
d7db7aa84f api-docs: Fix line break in API keys section. 2017-05-24 20:30:35 -07:00
Tim Abbott
47c8da28ff bots: Simplify automated testing library. 2017-05-24 20:13:25 -07:00
Tim Abbott
74ad90533d node: Fix missing bot_data initialization.
This was making the frontend tests fail.
2017-05-24 19:59:40 -07:00
derAnfaenger
4ec13d3693 bots: Simplify define bot test. 2017-05-24 19:44:22 -07:00
derAnfaenger
c3c7874e3f bots: Fix unit tests not running in Vagrant.
`test-bots` would not run in Vagrant, displaying
the error "ValueError: no such test method in <class
'bots_test_lib.BotTestCase'>: runTest" This was due to
the `BotTestCase` class inheriting from the TestCase
class, even though it was not a unit test on its own.

This commit removes the inheritance of TestCase and
specifies `test_define` as the `runTest` method in
`TestDefineBot`.
2017-05-24 19:44:22 -07:00
Vishnu Ks
bb98e35aa0 Replace othello@zulip.com with example_email('othello'). 2017-05-24 19:37:36 -07:00
Vishnu Ks
52d2d6c4fa Replace prospero@zulip.com with example_email('prospero'). 2017-05-24 19:37:36 -07:00
Vishnu Ks
c4db3b7d1c Replace cordelia@zulip.com with example_email('cordelia'). 2017-05-24 19:37:36 -07:00
Vishnu Ks
961b35d52e Replace iago@zulip.com with example_email('iago'). 2017-05-24 19:37:36 -07:00
Vishnu Ks
5230eaef1c Replace hamlet@zulip.com with example_email('hamlet'). 2017-05-24 19:37:36 -07:00
Vishnu Ks
b65f692fcf Make LoginEmailValidatorTestCase use ZulipTestCase instead of TestCase. 2017-05-24 19:23:48 -07:00
Krzysztof Krzysztof
5bc719ebbb bots: Add empty message support in Wikipedia bot. 2017-05-24 19:23:36 -07:00
Reid Barton
6d2a82ee3c build-release-tarball: Give helpful message on update-prod-static failure. 2017-05-24 19:17:00 -07:00
umkay
c1a8fb615c mypy: Fix strict-optional errors in webhooks directory. 2017-05-24 18:57:06 -07:00
Christian Hudon
8ab6a23a30 Fix most strict-optional issues in export.py. 2017-05-24 18:50:59 -07:00
Christian Hudon
1761a3b1c1 mypy: strict optional fixes. 2017-05-24 18:50:59 -07:00
Eklavya Sharma
2f227a97d3 mypy: Make zerver/lib/actions.py pass --strict-optional check. 2017-05-24 18:49:54 -07:00
Eklavya Sharma
1d8c316ff0 mypy: Make email_mirror pass --strict-optional check. 2017-05-24 18:49:54 -07:00
Eklavya Sharma
690b6025fb mypy: Fix return type of a function. 2017-05-24 18:43:51 -07:00
Mehanig
3f5d0e69fb Build and handle jsfiles using webpack instead of django-pipeline.
Also renames bundle.js to translations.js.
2017-05-24 18:38:03 -07:00
Mehanig
4f39d4fc22 Split webpack config into 3 files (base, dev, production). 2017-05-24 18:37:58 -07:00
Elliott Jin
573e06260a Don't initialize bot_data until after people.initialize()
bot_data initialization depends on the results of people.initialize(); for
example, to determine whether a bot is owned by the current user.
2017-05-24 17:58:57 -07:00
Steve Howell
6518c63b14 node tests: Add tests to activity.js. 2017-05-24 17:41:41 -07:00
Steve Howell
689605dd2e Introduce make_zjquery(). 2017-05-24 17:41:41 -07:00
Steve Howell
6c7a5260fc node tests: Add tests for filtering user ids in user list. 2017-05-24 17:41:41 -07:00
Steve Howell
5c09bec5e9 node tests: Use zjquery for entire activity test. 2017-05-24 17:41:41 -07:00
Steve Howell
ee17f8fc8d Move mousemove function into initialize(). 2017-05-24 17:41:41 -07:00
Steve Howell
46e72289d1 Add features to zjquery. 2017-05-24 17:41:41 -07:00
Steve Howell
4d6ca1ab70 Introduce compose_fade.initialize(). 2017-05-24 17:41:40 -07:00
Reid Barton
ccc2451b93 docs: Add missing single quote in EMAIL_FILE_PATH. 2017-05-24 17:37:49 -07:00
derAnfaenger
ba323faef6 bots: Make test-bots independent from current working path. 2017-05-24 17:34:11 -07:00
derAnfaenger
0965e3698d bots: Make run.py independent from current working path. 2017-05-24 17:34:11 -07:00
Christian Hudon
14e871ce9c Change order of arguments so output_dir is not optional. Helps mypy too. 2017-05-24 17:32:21 -07:00
Eeshan Garg
b5d271456a webhooks/trello: Use parametric Markdown macros. 2017-05-24 17:00:19 -07:00
Eeshan Garg
e9b3b56105 webhooks/appfollow: Use parametric Markdown macros. 2017-05-24 17:00:19 -07:00
Eeshan Garg
c433a7981a webhooks/airbrake: Use parametric Markdown macros for documentation. 2017-05-24 17:00:19 -07:00
Eeshan Garg
3cb758d339 templates: Support parametric Markdown macros for webhooks docs. 2017-05-24 17:00:19 -07:00
Reid Barton
2e4078cbd2 update-prod-static: Redirect update-authors-json stderr to log file. 2017-05-24 16:44:02 -07:00
Tim Abbott
e9968a7a09 change_user_email: Use new get_user_for_mgmt function. 2017-05-24 15:29:59 -07:00
Vishnu Ks
17b1a8b260 Add get_user_for_mgmt function. 2017-05-24 15:27:48 -07:00
Tim Abbott
6aaca44e17 tests: Fix str/Text mypy issues in various tests. 2017-05-24 15:19:38 -07:00
Andrew Archer
6c3f89af1c tests: Remove get_user_profile_by_email from numerous tests. 2017-05-24 15:19:20 -07:00
Krzysztof Krzysztof
cad50d8be1 bots: Add empty message support in Wikipedia bot. 2017-05-24 14:49:57 -07:00
Tim Abbott
65197aa11b version: Increase PROVISION_VERSION for mypy upgrade.
The new mypy version suppresses some bogus warnings.
2017-05-24 14:47:22 -07:00
derAnfaenger
5480f6fd0f bots: Refactor bots to use send_reply.
The send_reply function makes it easier for bots
to send messages. This commit updates all bots to
make use of this function, when possible.
2017-05-24 13:16:23 -07:00
Abhijeet Kaur
5ed6c29ccf tests: Add contrib_bots/test-bots file.
This test uses unittest and mock library. It mocks
'BotHandlerApi' class. This test works independent of
the rest of the code outside contrib_bots folder.

Merged with a few changes by tabbott to fix lint issues; we'll need to
do further work on this framework, but since it's not hooked up to
anything, it's reasonable to merge early so others can collaborate on
improving it.
2017-05-24 13:13:03 -07:00
Steve Howell
4cfd9aa689 Add test coverage for activity unread counts. 2017-05-24 13:08:54 -07:00
Steve Howell
4a062d47a6 Add more features to zjquery. 2017-05-24 13:08:54 -07:00
Steve Howell
884d9d1a2d Simplify unread count display logic in buddy list.
This commit de-couples the PM code from Group code.  It also
simplified some code related to finding parent elements by
both introducing local variables and removing unnecessary
selectors.
2017-05-24 13:07:33 -07:00
Rick Chern
e53d1c3885 tests: Remove get_user_profile_by_email from most tests. 2017-05-24 13:05:19 -07:00
root
e809faa37d docs: Document /users/me/subscriptions API endpoint. 2017-05-24 12:49:08 -07:00
Vishnu Ks
4403d179df tests: Replace mit_user().email with mit_email(). 2017-05-24 12:44:43 -07:00
Tim Abbott
e5f5e5c69f tests: Remove unnecessary maxDiff settings.
Now that ZulipTestCase does this, we don't need it in all these
individual test modules.
2017-05-24 12:43:28 -07:00
umkay
ccc70445d6 mypy: Fix strict-optional errors for test files.
Fix mypy --strict-optional errors in zerver/tests
2017-05-24 12:43:28 -07:00
Tim Abbott
17328a7557 tests: Fix incorrect use of get_realm_by_email_domain. 2017-05-24 12:43:28 -07:00
Cynthia Lin
344f284431 user docs: Document Streams menu hotkeys.
Also includes refactoring to **Keyboard shortcuts** user docs.
2017-05-24 12:19:15 -07:00
Cynthia Lin
2045426ab9 hotkeys: Change subscribe stream hotkey to S. 2017-05-24 12:19:15 -07:00
Cynthia Lin
6993f8900a subs: Focus in Filter streams input when menu is first opened. 2017-05-24 12:19:15 -07:00
Tim Abbott
895d4a795b mypy: Fix a missing type annotation. 2017-05-24 12:14:13 -07:00
Krzysztof Krzysztof
75794acc46 bots: Correct weird behavior of followup bot for empty messages.
Before it sends an empty message to followup stream, now it sends a
help message back to the user/stream where it was mentioned.
2017-05-24 11:58:12 -07:00
Mahim Goyal
44ff978ecb docs: Add a mounting shared folder error for vagrant.
I faced this problem many a times, might be of help to
beginners. Because, the same thing doesn't work when done through
`vagrant suspend` followed by `vagrant up`.
2017-05-24 11:54:00 -07:00
Yago González
40fa0f64f6 docs: Fix indentation. 2017-05-24 11:41:49 -07:00
Yago González
bd5fba4a64 docs: Fix inheritance in /messages/{message_id}. 2017-05-24 11:41:49 -07:00
Yago González
55664b1a93 docs: Fix JsonResponse definition. 2017-05-24 11:41:49 -07:00
Nick Dickey
6ac13a0f0d docs: Document /messages API endpoint. 2017-05-24 11:41:49 -07:00
Umair Khan
9a04fef71b testing: Reset active language.
After running translation tests, we should reset the active
language to isolate the change
2017-05-24 11:35:17 -07:00
Umair Khan
ebb9bd1a6a testing: Avoid class variables to enforce isolation.
Class variables are shared between all instances and as a result
changes made by one instance are leaked to other instances.
2017-05-24 11:35:12 -07:00
derAnfaenger
169f1e35b8 bots: Add incrementor bot.
This bot provides a sample implementation
for updating existing messages sent by the
bot.
2017-05-24 11:01:47 -07:00
derAnfaenger
0b2969a363 bots: Dedup rate limiting error code. 2017-05-24 11:01:47 -07:00
derAnfaenger
188f313e15 bots: Allow bots to update messages. 2017-05-24 11:01:46 -07:00
Tim Abbott
8aaf9b1426 Revert "Fix emoji cache setup when not using provision.py."
This reverts commit ab2cfadcaa.

This broke production installation.
2017-05-24 10:35:41 -07:00
Yago González
c0f2036435 api: Handle unregistered users in dev_fetch_api_key.
Fixes #4851.
2017-05-24 09:39:44 -07:00
Steve Howell
d5d6d47287 Fix unread counts for Group PMs.
The variable name "name" was completely wrong, and I guess
this never generated a traceback or lint error.
2017-05-24 09:18:24 -07:00
Steve Howell
a9f6f5f0c0 node tests: Split out presence.js. 2017-05-24 09:18:24 -07:00
Umair Khan
603b60940d github: Access private emails.
Previously our scope setting only allowed us access to
publicly listed email addresss. This commit changes that
to get access to private email addresses as well.

Fixes: #4937.
2017-05-24 08:24:26 -07:00
Mehanig
6038777891 npm: Upgrade webpack to 2.0 version dev and production. 2017-05-23 23:58:25 -07:00
Andrew Archer
67cf4c4fb4 test_alert_words: Remove use of get_user_profile_by_email. 2017-05-23 22:14:10 -07:00
Eklavya Sharma
2314c0fb1b tools/minify-js: Improve type checking.
* Use Optional where needed.
* Add type to variables because otherwise it'll be Any.
2017-05-23 22:02:41 -07:00
Eklavya Sharma
b805e0ca10 mypy: Assert non-Noneness.
Convince mypy that an object cannot be None by using an assert.
2017-05-23 21:56:50 -07:00
Eklavya Sharma
13ee26019f zproject/backends.py: Check for None before use.
Check if the dict 'return_data' is None before setting attributes
on it.
2017-05-23 21:56:50 -07:00
Eklavya Sharma
bac874b7e3 mypy: Allow None in passwords while creating users. 2017-05-23 21:56:50 -07:00
Eklavya Sharma
7636972a6c mypy: Wrap return value in Optional. 2017-05-23 21:56:50 -07:00
Eklavya Sharma
cc1937c8d5 mypy: Use Optional with strings where required. 2017-05-23 21:56:50 -07:00
Eklavya Sharma
481d14df39 mypy: Remove a type: ignore.
https://github.com/python/typeshed/pull/693 was merged.
2017-05-23 21:56:48 -07:00
kb0rg
eb2d0ebd09 Add test for do_deactivate_realm exit if deactivated.
Rename existing test_do_deactivate_realm to indicate test purpose
is to confirm user realm cache clears when a realm is deactivated.
2017-05-23 21:38:07 -07:00
kb0rg
e672ec62c1 Add test for encode_email_address with empty Gateway. 2017-05-23 21:38:07 -07:00
kb0rg
d625cca2f8 minor: Rename test class -> TestEmptyGatewaySetting. 2017-05-23 21:38:07 -07:00
vaibhav
f94c321567 Outgoing Webhook System: Add support for personal message triggers. 2017-05-23 21:35:09 -07:00
Tim Abbott
ed82f6f3d0 contrib_bots: Fix lint errors in virtual_fs.py. 2017-05-23 21:35:09 -07:00
neiljp
a859dadd29 contrib_bots: Clean up and document virtual_fs bot. 2017-05-23 21:04:34 -07:00
Lech Kaiel
6b49e667ef tests: Replaced @zulip.com references with self.example_ functions.
This cleans up the excessive use of @zulip.com emails in the tests.
2017-05-23 20:59:50 -07:00
Abhijeet Kaur
aa576d83b0 Refactor: Make StateHandler() function independent.
This refactor makes the nested class 'StateHandler' in the
file /contrib_bots/bot_lib.py independent class. It previously
was nested in 'run_message_handler_for_bot' function.

This is done to write a cleaner test file for contrib_bots using
mock library.
2017-05-23 20:42:09 -07:00
Brian Tenazas
9d485a0415 docs: Document /streams API endpoint. 2017-05-23 20:37:51 -07:00
Yago González
9f329f6597 docs: Fix JsonSuccess and JsonError models. 2017-05-23 20:37:51 -07:00
Mark Shannon
c7c47fe11d Replace buggy NotImplemented with NotImplementedError(). 2017-05-23 20:33:35 -07:00
Yago González
b668b869c1 docs: Improve /messages/{message_id} PATCH. 2017-05-23 20:32:46 -07:00
Yago González
90301a4d93 docs: Fix indentation in lines started with a hyphen. 2017-05-23 20:30:21 -07:00
Yago González
1fc1cafd6f docs: Make Swagger "require" fields uniform.
As the Swagger specification indicates, whether the properties inside a
model are required or not must be defined inside a separate "required"
field at the root of the model.

For fields like "parameters", that has to be specified inside each
parameter's key.
2017-05-23 20:30:21 -07:00
Yago González
fa081146d1 docs: Remove unnecessary "produces" keys. 2017-05-23 20:30:21 -07:00
Yago González
735fc5e0cd docs: Remove unnecessary ErrorModel definition. 2017-05-23 20:30:21 -07:00
Yago González
4bb1c566a9 docs: Remove "optional" notes in descriptions. 2017-05-23 20:30:21 -07:00
Yago González
d56ec79dd9 docs: Create JsonSuccess and JsonError definitions. 2017-05-23 20:30:21 -07:00
ron-s
e5d4e0f0eb Test: Add test_notify_of_new_user_internally. 2017-05-23 20:27:37 -07:00
Theodore Chen
c29e0b4c32 docs: Recommend testing contrib_bots with helloworld bot. 2017-05-23 20:22:40 -07:00
Theodore Chen
42f9cdcc78 bots: Fix googlesearch bot exceptions and add readme. 2017-05-23 20:18:24 -07:00
derAnfaenger
74069561f1 bots: Fix converter bot.
The converter bot depended on past.utils.old_div,
which is not supported anymore. Updating the code
to use the // operator, which provides the same
functionality.
2017-05-23 20:13:29 -07:00
Steve Howell
5003283b64 Enforce 100% test coverage for lib/avatar.py. 2017-05-23 20:07:07 -07:00
Steve Howell
c02f4b4756 Add people.initialize().
This makes us not have to stub jquery in many of our node
tests!
2017-05-23 19:35:08 -07:00
Joshua Pan
43487c6c3f node_tests: Get unread.js to 100% node coverage. 2017-05-23 19:04:02 -07:00
Joshua Pan
d44626d456 node_tests: Get topic_generator.js to 100% node coverage. 2017-05-23 19:00:56 -07:00
Steve Howell
7c1b555331 node tests: Use zjquery for common.js tests. 2017-05-23 18:52:25 -07:00
Steve Howell
1cb58d72b2 zjquery: Add focus/blur methods. 2017-05-23 18:52:25 -07:00
Steve Howell
cd08bbe7d8 zjquery: Add array-like functionality to elements.
(We simulate the behavior that a jquery object looks like an
array, but also has methods that can be called as if it were a
scalar.)
2017-05-23 18:52:25 -07:00
Steve Howell
4c520780a1 zjquery: Support $(func) flavor of $() calls. 2017-05-23 18:52:25 -07:00
neiljp
fb9ea6b0d9 contrib_bots: Update xkcd bot to use send_reply.
This enables private message usage.
2017-05-23 18:43:43 -07:00
Steve Howell
036f66aba3 Add test_get_avatar_url_with_user_profile_lookup test. 2017-05-23 18:35:45 -07:00
Vishnu Ks
b5c4a95ef1 test_bots.py: Use example_email instead of using the emails directly. 2017-05-23 18:31:43 -07:00
Vishnu Ks
dbdc0220b9 test_presence.py: Remove unused get_user_profile_by_email import. 2017-05-23 18:31:43 -07:00
neiljp
62ac170880 contrib_bots: Remove triage_message() from help bot.
This completes removing triage_message from the tree.
2017-05-23 18:30:39 -07:00
Jason Michalski
a22d6d2c2a test-backend: Enable test coverage in multi-process mode.
We enable data_suffix option when creating Coverage instances which
causes the output files to include the hostname, pid, and random id.
Before each run erase is called which clears all existing coverage data
files. And then at the end of the test run use the combine method which
merges the reports.

We collect coverage in the main process which collects data from
imports and also when running in single process mode. In the workers we
collect coverage in run_subsuite. This creates more stats files than
strictly required but I don't see a better place to save the stats when
stopping workers.

Note that this has the side effect of enabling parallel testing in
Travis CI.
2017-05-23 18:25:13 -07:00
Tim Abbott
109c5c677a mypy: Fix return value annotation for google_oauth2_csrf. 2017-05-23 17:47:03 -07:00
Tim Abbott
17f87cfc9e mypy: Fix missing Optional on process_exception. 2017-05-23 17:44:30 -07:00
Tim Abbott
315a9ee72e handlers: Fix type of zulip_finish. 2017-05-23 17:36:19 -07:00
neiljp
8b25766ff2 contrib_bots: Switch encrypt bot to use send_reply. 2017-05-23 17:32:51 -07:00
Tim Abbott
207c30fc9c Revert "settings: Fix missing status report when waiting period disabled."
This reverts commit a25e7451f6.

This changed the wrong if statement in this file.
2017-05-23 17:02:35 -07:00
neiljp
d766687632 bots: Switch define bot to use send_reply. 2017-05-23 17:02:03 -07:00
Steve Howell
ecdc500440 test-backend: Run only one process for --rerun option. 2017-05-23 16:59:22 -07:00
Sarah
01cb480b2c settings-org.js: Create property_types object and refactor set_up.
Create property_types object for realm settings. In set_up function,
iterate over property_types to find settings that were updated, send those
new values to the server, and report that the changes were made.
2017-05-23 16:32:36 -07:00
Tim Abbott
a25e7451f6 settings: Fix missing status report when waiting period disabled.
Previously, if one set the waiting period threshhold to 0, no
notification would be produced, even though the actual state of the
world was changed.
2017-05-23 16:31:41 -07:00
Sarah
4c4444b2dc zerver/lib/actions: Fix PEP8 E712 error. 2017-05-23 16:29:49 -07:00
Tim Abbott
796cf8e5fd mypy: Fix a buggy annotation in create_mirrored_message_users. 2017-05-23 15:45:56 -07:00
Andrew Archer
40b3330f2c actions: Refactor get_user_profile_by_email to get_user. 2017-05-23 15:30:14 -07:00
Vishnu Ks
2b36df6b8f test_sessions.py: Use helpers instead of get_user_profile_by_email. 2017-05-23 15:27:21 -07:00
Vishnu Ks
dafa89d52b test_outgoing_webhook_system.py: Replace get_user_profile_by_email with example_user. 2017-05-23 15:27:21 -07:00
Vishnu Ks
f5d8e256aa Add ZulipTestCase.example_email and ZulipTestCase.mit_email function. 2017-05-23 15:27:21 -07:00
Vishnu Ks
075b0cae70 test_bugdown.py: Remove unused get_user_profile_by_email import. 2017-05-23 15:27:21 -07:00
Vishnu Ks
7950f5242a test_unread.py: Replace get_user_profile_by_email with get_user. 2017-05-23 15:27:21 -07:00
Vishnu Ks
789ef217a8 send_email.py: Remove unused get_user_profile_by_email import. 2017-05-23 15:27:21 -07:00
Tim Abbott
a833fa39b8 test_messages: Fix tests failing due to error message change. 2017-05-23 15:27:21 -07:00
Ryan Backman
973b18bf2f docs: Document messages/{message_id}. 2017-05-23 15:01:26 -07:00
Yago González
83f3959906 api: Remove unnecessary period for consistency. 2017-05-23 15:01:26 -07:00
Matt Long
19363b2b77 notification_settings: Refactor notification preference settings.
Previously, all notification preference setting had a dedicated test
and setter. Now, all are handled through a modular function using the
property_types framework.
2017-05-23 14:47:46 -07:00
neiljp
fe1fc45a9e bots: Fix help bot replies in private chat, including 3+ users.
Also deduplicates the code.
2017-05-23 14:38:49 -07:00
Christian Hudon
c80e6edb4e mypy: Declare models with null=True Optional. 2017-05-23 14:36:40 -07:00
Theodore Chen
d2090306ad bots: Add helloworld example bot. 2017-05-23 13:15:21 -07:00
neiljp
13649d8846 Factor out send_reply functionality into bot_lib 2017-05-23 12:40:08 -07:00
Rick Chern
70d68f7e71 Refactoring: Replace get_user_profile_by_email() in lib/upload.py 2017-05-23 12:37:49 -07:00
Yago González
15da8d19e7 docs: Update API authentication definitions. 2017-05-23 12:35:41 -07:00
Steve Howell
484f32646b Rename file to test_new_users.py.
The old file name of test_send_login_emails was
overly specific, and we want to add some tests
related to other parts of the signup process.
2017-05-23 12:34:44 -07:00
Joshua Pan
25b61f2af6 message_edit: Close edit with ESC.
Fixes #3797.
2017-05-23 12:34:08 -07:00
Eklavya Sharma
63cc8183ad tools/run-mypy: Add flags. 2017-05-23 12:02:57 -07:00
Eklavya Sharma
bda5517b5c mypy: Upgrade to latest version of mypy. 2017-05-23 10:42:44 -07:00
umkay
8611dae985 mypy: Change type annotation to Set[bytes].
also fix unicode
2017-05-23 10:42:44 -07:00
umkay
dd55d5b683 mypy: Fix bad type annotation 2017-05-23 10:42:44 -07:00
umkay
09e1136cc8 mypy: Fix casing for List type. 2017-05-23 10:42:44 -07:00
umkay
a67e427293 mypy: Add comment for future use of Deque.
In the future, the type annotation should use Deque in order to be
compatible with the latest mypy version. See
https://github.com/python/mypy/pull/2845 for more info.
2017-05-23 10:42:44 -07:00
Joshua Pan
c955028350 gear_menu.js: Fix typo. 2017-05-23 10:34:07 -07:00
Joshua Pan
c78b310381 hotkeys: Close clicked gear menu with ESC.
Fixes #4200.
2017-05-23 10:34:07 -07:00
Konstantin Gukov
c40759562c streams: Refactor get_user_profile_by_email to get_user. 2017-05-23 10:32:53 -07:00
Konstantin Gukov
dd76222a3f Fetch system bots using new get_system_bot function.
This eliminate a bunch of uninteresting calls to
get_user_profile_by_email.
2017-05-23 10:30:40 -07:00
Joshua Pan
f3369b266a node_tests: Extract and create fake_jquery as zjquery.
This allows us to use fake_jquery (originally only in
compose_actions.js) in all our node tests.
2017-05-23 10:27:07 -07:00
Joshua Pan
f8e10ed2f6 node_tests: Add test coverage to autofocus. 2017-05-23 10:26:30 -07:00
Joshua Pan
525cc34491 node_tests: Add test for long low-quality passwords. 2017-05-23 10:26:30 -07:00
vaibhav
287aaa21b6 Outgoing Webhook System: Add outgoing webhook queue worker. 2017-05-23 08:21:08 -07:00
vaibhav
c7524f2f38 Outgoing Webhook System: Prevent infinite loops with outgoing webhooks. 2017-05-23 08:20:45 -07:00
vaibhav
53a8b2ac87 Outgoing Webhook System: Add DoRestCall and helper functions 2017-05-23 08:19:16 -07:00
neiljp
66d8464d2c Update Wikipedia bot to reply to multiple user private chats. 2017-05-23 08:17:35 -07:00
Tim Abbott
454421e098 bot_lib: Fix indentation. 2017-05-23 08:17:22 -07:00
derAnfaenger
2e298d89ab bots: Strip leading whitespaces from bot queries. 2017-05-22 19:13:42 -07:00
derAnfaenger
e74714f6ac bots: Clarify message handling for @-mentions. 2017-05-22 19:13:42 -07:00
derAnfaenger
b90a5f60e2 bots: Allow empty bot queries.
This commit allows bots to be adressed with empty queries,
that is, by just @-mentioning them. @-mentioning is now the
only way to adress a bot.
2017-05-22 19:13:42 -07:00
Tim Abbott
e1f6b8135f docs: Fix long lines in accessibility document. 2017-05-22 19:12:43 -07:00
Vishnu Ks
820dc9dd9a Replace espuser@mit.edu with mit_user('espuser'). 2017-05-22 19:02:42 -07:00
Vishnu Ks
99fc0e9e62 Replace starnine@mit.edu with mit_user('starnine'). 2017-05-22 19:02:42 -07:00
Vishnu Ks
c680c5f1e8 Replace sipbtest@mit.edu with mit_user('sipbtest'). 2017-05-22 19:02:42 -07:00
Vishnu Ks
7f06a7fa2a Add ZulipTestCase.mit_user() function. 2017-05-22 19:02:42 -07:00
Vishnu Ks
05951074be Make MITNameTest use ZulipTestCase instead of TestCase. 2017-05-22 19:02:42 -07:00
Jeremy Bowman
cdb4d9852b Add accessibility documentation. 2017-05-22 18:46:02 -07:00
Tim Abbott
835f0c9961 HTML: Fix duplicate useless IDs in message_edit_form.
These ID elements in the message edit forms were never used, and were
they used, would have been broken anyway.  We fix this by just
removing them.

Fixes #4913.
2017-05-22 18:40:21 -07:00
Cynthia Lin
b1f94cb173 user docs: Update message UI screenshots.
Fixes #4763
2017-05-22 18:35:22 -07:00
Cynthia Lin
bef256ebbb user docs: Update login button screenshots. 2017-05-22 18:35:22 -07:00
Cynthia Lin
d21264d4b0 user docs: Update search bar UI screenshots. 2017-05-22 18:35:22 -07:00
Cynthia Lin
7175d79e21 user docs: Update settings/organization modal screenshots. 2017-05-22 18:35:22 -07:00
Cynthia Lin
eba2ee9cba user docs: Update Invite users screenshots. 2017-05-22 18:35:22 -07:00
Cynthia Lin
e4543a98ff user docs: Update Streams modal UI screenshots. 2017-05-22 18:35:22 -07:00
Cynthia Lin
a88c5091bd user docs: Update custom link filter screenshots. 2017-05-22 18:35:22 -07:00
Cynthia Lin
6b9dfcec4e user docs: Delete *View information about a message* doc.
Deprecated feature; replaced by message sender info.
2017-05-22 18:35:22 -07:00
Cynthia Lin
561cb64f33 user docs: Update docs with compose box UI changes. 2017-05-22 18:35:22 -07:00
Cynthia Lin
f0c5b68a5e user docs: Delete *Restore the last unsent message* doc.
Deprecated feature; Drafts feature has replaced it.
2017-05-22 18:35:22 -07:00
Cynthia Lin
314a506890 user docs: Update *The Zulip browser window* doc. 2017-05-22 18:35:22 -07:00
Cynthia Lin
226e30d9ea user docs: Update *Add custom emoji* doc. 2017-05-22 18:35:22 -07:00
Cynthia Lin
58bec1aa37 user docs: Update right sidebar images. 2017-05-22 18:35:22 -07:00
Cynthia Lin
bfcb0552e8 user docs: Merge *The announce stream* and *Make an announcement* docs. 2017-05-22 18:35:22 -07:00
Cynthia Lin
6977232dcc user docs: Update *Zulip on Android* doc. 2017-05-22 18:35:22 -07:00
Cynthia Lin
5628e467ac user docs: Update *Send message in a different language* doc. 2017-05-22 18:35:22 -07:00
Cynthia Lin
8211e19074 user docs: Update *Format your messages using Markdown* with UI changes. 2017-05-22 18:35:22 -07:00
Cynthia Lin
bafa976376 user docs: Update *Add a bot or integration* with UI changes. 2017-05-22 18:35:22 -07:00
Cynthia Lin
eb472411ce user docs: Document status messages in Message formatting docs.
Removes *Send a status message*. Fixes #4522.
2017-05-22 18:35:22 -07:00
Ryan Backman
3d54607788 docs: Document user_upload. 2017-05-22 18:24:26 -07:00
Eeshan Garg
ed8c6943f2 webhooks/airbrake: Use Markdown macros for documentation. 2017-05-22 18:19:14 -07:00
Eeshan Garg
2e3081e93d webhooks: Add Markdown macros for repetitive documentation. 2017-05-22 18:19:14 -07:00
Eeshan Garg
baff121115 app_filters: Render HTML to render Jinja2 syntax within Markdown macros.
If a Markdown macro contains Jinja2 template code, it isn't rendered
because render_markdown_path calls template.render on the including
.md file before the macro has been included. And then the including
.md file is converted to HTML. Therefore, the template code within
a Markdown macro (if any) never gets rendered and is returned as it is.

Now, after the source .md file is converted to HTML,
render_markdown_path renders the resulting HTML so that any template
code within included macros (if any) is finally rendered.
2017-05-22 18:19:14 -07:00
Josiah Philipsen
df7eaa8868 docs: Document user presence endpoint. 2017-05-22 18:18:20 -07:00
JoshuaGoldin
0b88957d12 views: Use property_types for display settings.
This reduces semi-duplicated code here.
2017-05-22 18:11:08 -07:00
Eeshan Garg
3843f191b4 api: Use the console_scripts entry point to point to zulip-send.
Instead of using the `scripts` keyword, we now use the
`console_scripts` entry point to point to the zulip-send script
to be installed. This is what the Python Packaging User Guide
recommends for better cross-platform compatibility.
2017-05-22 18:08:18 -07:00
Lukasz Prasol
5eaccc550a rate_limit: Make retry-after data machine-readable.
Fixes #4831.
2017-05-22 17:35:12 -07:00
Lukasz Prasol
01f7d9d651 zerver/lib/events: Refactor get_user_profile_by_email to get_user.
Fixes #4831.
2017-05-22 17:32:36 -07:00
Elliott Jin
759d4450c3 bots: Allow symlinks in bot paths provided to run.py.
run.py requires that the location of the provided bot matches the location
of run.py.  However, run.py previously failed in the case where the location
included a symlink.
2017-05-22 16:52:29 -07:00
Elliott Jin
ce9c3b7a0f Add clarifications to bots guide. 2017-05-22 16:51:29 -07:00
Brendan Kiu
082f451885 lightbox: update help text for v shortcut.
New behavior of the `v` shortcut updated in documentation.

Follow up to #4869
2017-05-22 16:48:37 -07:00
Tim Abbott
accc7406da views/presence: Refactor get_user_profile_by_email -> get_user. 2017-05-22 16:43:08 -07:00
Lech Kaiel
7995dd2de6 views/users: Refactor get_user_profile_by_email to get_user. 2017-05-22 16:42:16 -07:00
Brendan Kiu
361ba50a54 lightbox: select nearest image on 'v' hotkey.
Loop through previous messages to find first instance of a valid image.

Fix: #4217.
2017-05-22 15:02:38 -07:00
Josiah Philipsen
d72c961ab2 zulip.yaml: Change unexpected error with proper results.
The error message under "Unexpected errors" was not the format we
received for any errors. We changed it to be msg and result to fit
with the results we got when for standard Zulip JSON errors.
2017-05-22 14:42:48 -07:00
Jordan Gedney
36406b6a25 mypy: Add type: ignores for optparse.OptionGroup.
Typeshed has already fixed this upstream (Description is optional)
2017-05-22 14:40:48 -07:00
Jordan Gedney
2c21c26b50 mypy: PySvn Client.Log returns a dictionary mapping to many different types. 2017-05-22 14:39:26 -07:00
umkay
510b7a0489 mypy: Add ignore type for dynamically added field on LogRecord.
mypy will error because of the attribute "request" on the LogRecord
object. Since this field is added in our tests dynamically and is not
on the base object, for now we will ignore the type.
2017-05-22 14:38:39 -07:00
Elliott Jin
59bfc9bf69 Clean up bots guide.
Due to the directory symlink structure in the dev VM, including the
`~/zulip/contrib_bots/` prefix in the command for running a bot causes
`run.py` to fail with an error.
2017-05-22 13:49:02 -07:00
umkay
c8a203b438 mypy: Change type annotation from union to explicit set 2017-05-22 13:47:55 -07:00
Vishnu Ks
bdf7c6c02f models: Add get_user function.
This is intended to replace get_user_profile_by_email.
2017-05-22 11:26:44 -07:00
Jordan Gedney
a9f4d56a95 mypy: Add type to info dictionary. 2017-05-22 11:19:06 -07:00
Robert Hönig
9fcd63bdf9 docs: Refine bots-guide.md. 2017-05-22 11:18:14 -07:00
Carey Metcalfe
c2c7377719 Fix documentation for Debian Jessie
Adds some dependancies and specialized instructions for installing
pgroonga.
2017-05-22 11:08:43 -07:00
Carey Metcalfe
ab2cfadcaa Fix emoji cache setup when not using provision.py.
Moves creating the emoji folder from the provisioning script to
the build_emoji script.

Fixes the fact that the emoji cache directory wasn't being created
when not using the provision.py script.
2017-05-22 11:08:43 -07:00
Yago González
f9f00374d6 api: Add Swagger YAML file.
Authored-By: Andrea Longo
2017-05-22 10:29:24 -07:00
theopen-institute
7eaa1fa0d0 create-production-venv: Fix symlink creation.
The install script was failing on 2nd+ attempts if the first attempt
was interrupted.

This failure happened because zulip-venv already existed at
`current_venv_path`. Changing the `ln` command's flags from `-s` to
`-nsf` should make this part of the script idempotent.
2017-05-20 21:31:50 -07:00
Tim Abbott
a2f5d133e8 docs: Document the push notification forwarding service. 2017-05-18 13:39:58 -07:00
Steve Howell
e00f9f3dcb Split out Organization Permissions page. 2017-05-18 12:37:03 -07:00
Joshua Pan
3e4fb01685 changelog: Minor grammar and wording changes. 2017-05-17 18:42:48 -07:00
Tim Abbott
040067b2a2 invite: Remove obsolete bulk_invite_users endpoint. 2017-05-17 17:30:15 -07:00
Aditya Bansal
092d670e85 pep8: Add compliance with rule E261 to zerver/views/user_settings.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
cc2b334020 pep8: Add compliance with rule E261 to zerver/views/streams.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
11aeeec2ab pep8: Add compliance with rule E261 to zerver/views/registration.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
5cdfd899dc pep8: Add compliance with rule E261 to zerver/views/realm.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
db3c05002a pep8: Add compliance with rule E261 to zerver/views/presence.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
634c08c3dd pep8: Add compliance with rule E261 to zerver/views/messages.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
35e3d57ed9 pep8: Add compliance with rule E261 to zerver/views/invite.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
1979476152 pep8: Add compliance with rule E261 to zerver/views/integrations.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
fe3b42c8f8 pep8: Add compliance with rule E261 to zerver/views/home.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
c504b013b1 pep8: Add compliance with rule E261 to views/auth.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
521bdccb9d pep8: Add compliance with rule E261 to test-tools. 2017-05-18 03:00:32 +05:30
Aditya Bansal
8b219bea13 pep8: Add compliance with rule E261 to test-api. 2017-05-18 03:00:32 +05:30
Aditya Bansal
306e74c60d pep8: Add compliance with rule E261 to replace-tarball-shebang. 2017-05-18 03:00:32 +05:30
Aditya Bansal
d6f97f09aa pep8: Add compliance with rule E261 to renumber-migrations. 2017-05-18 03:00:32 +05:30
Aditya Bansal
171a0ddd4e pep8: Add compliance with rule E261 to minify-js. 2017-05-18 03:00:32 +05:30
Aditya Bansal
cd7fda993a pep8: Add compliance with rule E261 to lint. 2017-05-18 03:00:32 +05:30
Aditya Bansal
4d06c567f4 pep8: Add compliance with rule E261 to html-grep. 2017-05-18 03:00:32 +05:30
Aditya Bansal
151712b9cc pep8: Add compliance with rule E261 to get-handlebar-vars. 2017-05-18 03:00:32 +05:30
Aditya Bansal
bc987c99ca pep8: Add compliance with rule E261 to create-test-api-docs. 2017-05-18 03:00:32 +05:30
Aditya Bansal
9c29da17fc pep8: Add compliance with rule E261 to compile-handlebars-templates. 2017-05-18 03:00:32 +05:30
Aditya Bansal
57bc847874 pep8: Add compliance with rule E261 to test_urls.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
85aa07e2d4 pep8: Add compliance with rule E261 to zerver/lib/upload.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
b7c49299a6 pep8: Add compliance with rule E261 to test_runner.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
e3003653c7 pep8: Add compliance with rule E261 to test_helpers.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
26ff19f005 pep8: Add compliance with rule E261 to zerver/lib/test_classes.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
1f1fbd7648 pep8: Add compliance with rule E261 to zerver/lib/notifications.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
84eadc0562 pep8: Add compliance with rule E261 to zerver/lib/message.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
03e43b78ee pep8: Add compliance with rule E261 to zerver/lib/html_diff.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
b822e75a4b pep8: Add compliance with rule E261 to export.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
4c373dde63 pep8: Add compliance with rule E261 to events.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
1a184263b8 pep8: Add compliance with rule E261 to zerver/lib/db.py. 2017-05-18 03:00:32 +05:30
Aditya Bansal
420230b342 pep8: Add compliance with rule E261 to actions.py. 2017-05-18 03:00:32 +05:30
Greg Price
d76e9b7d71 docs: Add Vagrant instructions for Debian "stretch".
Aka the current "testing" release, expected to graduate to "stable"
later in 2017.

Fortunately the instructions are very similar to those for
Ubuntu 16.04 and 14.04 -- two packages don't exist, and
those two packages turn out (empirically, on my laptop)
not to be necessary.

Leave most references to "Ubuntu" still just saying "Ubuntu",
on the theory that Debian users will generally follow those
breadcrumbs where they lead and in order to keep lists short.
2017-05-17 13:04:30 -07:00
Brock Whittaker
a88ca9fafc emoji-reactions: Fix reactions to not break inline-block display.
This fixes the reactions to not break a new line by changing them from
a weird combination of “float: left” and “display: block” (inlined), to
just “display: inline-block”.

With fixes from Harshit Bansal for an issue with using the hotkeys in
a filtered popover.

Fixes: #4818.
2017-05-17 12:49:40 -07:00
Umair Khan
bc15085098 gcm: Increase retries to 10 while pushing. 2017-05-17 12:14:32 -07:00
Umair Khan
38ecc35cd9 push_notifications: Catch IOError while pushing to GCM. 2017-05-17 12:14:32 -07:00
Tim Abbott
e12d3100db settings: Fix whitespace leak in organization description.
Previously, the way the organization description textarea was
generated, there'd be a newline and ~12 spaces added each time on
reloaded the page and hit "save changes".

This change makes it so that the organization description only changes
when the user actually changes it.
2017-05-17 12:11:10 -07:00
Brock Whittaker
ed767481f5 settings: Clean up organization and user settings pieces.
This cleans up the styling of the organization and the user settings
components to be more responsive and have more consistent styling with
the rest of the overlays.
2017-05-17 12:08:31 -07:00
Tim Abbott
6e66495c38 auth: Fix authentication methods checkboxes disabling.
Apparently, there were not correctly disabled if you clicked on
"authentication methods" after opening the settings UI another way.
Everything worked fine if you just clicked them, already.
2017-05-17 11:54:55 -07:00
Brock Whittaker
b00f7f09bc components: Darken checkbox default color.
This darkens the default checkbox color to be more contrasty as to not
look like they are disabled.
2017-05-17 11:54:55 -07:00
Steve Howell
3ca10dd6f5 Select first unread message when using the "n" key. 2017-05-17 11:28:33 -07:00
Steve Howell
d0ea11f355 Have "n" key skip muted streams. 2017-05-17 11:28:33 -07:00
Steve Howell
6f73b7953f Have "n" key skip muted topics. 2017-05-17 11:28:33 -07:00
Harshit Bansal
d827cc878b emoji.js: Remove unnecessary indirection.
Remove unnecessary function `emoji_name_to_css_class()` called while
populating `emojis_name_to_css_class` dict.
2017-05-17 08:09:50 -07:00
Harshit Bansal
bf97734c57 reactions: Fix broken rendering of flag emojis in reactions.
Use the patched css classes for rendering flag emojis in reactions.
2017-05-17 08:09:50 -07:00
Harshit Bansal
a549013c50 emoji_pickers: Fix broken flag emojis.
Due to differences between the codepoints of flag emojis in
`emoji_map.json` and iamcal's dataset, we need to patch the
css classes for the flag emojis temporarily until the migration
to iamcal's dataset is complete inorder to render them properly.
There is a difference between the images of flag emojis in our
old emoji farm and iamcal's spritesheets and since we have not
yet switched to using spritesheets for displaying emojis in
messages, there is a difference between the flag emojis as
rendered in messages and in emoji pickers.
2017-05-17 08:09:50 -07:00
Umair Khan
7e8f4ca4e8 push_notifications: Include GCM in end-to-end test. 2017-05-17 08:09:19 -07:00
Steve Howell
7d153c9f8a Revert "muting.js: Track muted streams using stream id."
This reverts commit c7f710b8d4.

Because the back end still stores muted topics fundamentally using
stream name as a key, trying to cut over the client to use stream
id was just making things more brittle.  Mutes would work after
renaming the stream, which was progress in the change that we
revert here, but only until page load.  The other problem, which
is more severe, is that the order of page loading functions would
cause no mutes to happen at page load time.  This could be fixed
to some degree, but we should do a deeper fix on the back end.
2017-05-17 07:06:32 -07:00
Tim Abbott
11adbf5783 generate_secrets: Fix placement of mypy type: ignore. 2017-05-17 00:05:57 -07:00
Tim Abbott
a6af57e90d css: Fix floating recipient bar border appearing when bar hidden.
It's the .recipient_row, not the .floating_recipient element, that
gets `display: none` added when the floating recipient bar is hidden.
2017-05-16 23:50:38 -07:00
Rishi Gupta
8b9929e771 alerts: Restyle alert banners.
Changes the background to be white, among other things.
2017-05-16 23:34:45 -07:00
Cory Lynch
24cbd61131 css: Fix KaTeX summation alignment and line wrapping.
Previously, the sum (capital sigma) operator would become
misaligned so that the lower and upper bounds are placed in
the wrong location. Changing the line height fixes this alignment.

Also, previously, wrapping long lines of TeX did not work, as often,
the different lines of math would overlap with each other.

Fixes #4657.
2017-05-16 23:29:36 -07:00
Tim Abbott
b01ba5f389 generate_secrets: Fix mypy errors.
I'm pretty sure these errors reflect a problem with Typeshed, but
don't have time to investigate.
2017-05-16 23:28:44 -07:00
Tim Abbott
45a4aeac64 scripts: Run generate_secrets.py during the upgrade process.
Now that generate_secrets.py is idempotent, this allows us to
conveniently add new secrets whenever they are required.
2017-05-16 22:15:26 -07:00
Tim Abbott
2c6a91e24a scripts: Make generate_secrets.py idempotent.
Now, generate_secrets.py will never overwrite existing secrets.  In
addition to being a safer model in generate, this fixes 2 significant
issues:

(1) It makes it much easier to preserve secrets like Oauth tokens in a
development environment (previously, provision would destroy them).
(2) It makes it possible to automatically add new secrets as part of
the upgrade process.  In particular, this is useful for the
zulip_org_id settings.

Fixes #4797.
2017-05-16 22:15:25 -07:00
Tim Abbott
03b5200d8b generate_secrets: Reformat list of autogenerated secrets. 2017-05-16 22:15:25 -07:00
Tim Abbott
f970ea935b docs: Update changelog. 2017-05-16 21:39:11 -07:00
Tim Abbott
be3dc12a98 models: Move several __unicode__ methods to abstract classes.
This makes it possible to print ArchivedMessage, ArchivedUserMessage,
and ArchivedAttachment objects.
2017-05-16 21:04:58 -07:00
Tim Abbott
34a8e6c3a2 gear_menu: Eliminate scrollTop for non-home tabs.
We should be able to eventually further clean this up to do nothing,
since we now don't have tabs over than the home tab.  But I'm leaving
that for a future issue.
2017-05-16 20:37:00 -07:00
Tim Abbott
72720fcf2e settings: Remove obsolete message_viewport.scrollTop() calls.
These date from long before the settings UI was restructured as an
overlay.  Now, instead of ensuring that error messages are visible,
they just scroll the message feed incorrectly.

Fixes #4810.
2017-05-16 20:33:52 -07:00
Tim Abbott
850519b314 api: Move cross_realm_bots into the register_ret response.
This is probably not the right long-term solution to the cross-realm
bots problem (that solution is probably to eliminate cross-realm bots
and replace them with per-realm bots).  But in the short term, this
will at least make it possible for mobile apps to interact with these
cross-realm bots using the `realm_user` data set.
2017-05-16 20:23:13 -07:00
Eeshan Garg
4f358f4034 webhooks/gitlab: Support pushing a local branch without commits.
This mostly just adds a test for GitLab related to the last commit.
2017-05-16 19:33:43 -07:00
Eeshan Garg
5687b2cdc5 webhooks/github*: Support pushing a local branch without commits.
Changes made to get_push_commits_event_message in
zerver/lib/webhooks/git.py are common to all Git integrations
that use get_push_commits_event_message. These include github,
github_webhook, gitlab, gogs, bitbucket, bitbucket2. In some
cases (for instance, gitlab), no further changes to gitlab/view.py
will be required to support pushing a local branch without commits;
adding a fixture and tests should suffice.
2017-05-16 23:51:19 -02:30
Tim Abbott
7a545eeb13 docs: Update copyright notices for 2017.
Also record Kandra Labs, Inc., as a major copyright holder.
2017-05-16 19:04:59 -07:00
Tim Abbott
cab908b664 api: Move notifications_stream into the register_ret API.
While we're at it, we at least fix the API to use a stream ID, not a
stream name, to refer to the notifications stream.
2017-05-16 18:57:14 -07:00
Tim Abbott
8c172063e0 message_fetch: Increase batch size for message backfill to 1000.
There's no advantage to doing a small batch size towards current here,
since latency isn't an issue at this point, and performance on the
server side generally favors larger batch sizes.

This also will make it significantly harder to start getting 429 rate
limiting errors when loading when far behind current.
2017-05-16 18:32:48 -07:00
Tim Abbott
b64a4f9291 minify-js: Fix failure to update JS files on Git deploys.
This fixes a significant static asset pipeline bug, which mean that
when we added `moment.js` to the Zulip npm dependencies, it wasn't
properly included in common.js; caching prevented common.js from ever
being rebuilt.
2017-05-16 17:57:20 -07:00
David
942520123c message view: Render formal date string as tooltip on recipient row
A formal date string will be assigned to the title attribute of the
recipient_row_date and date_row elements.
e.g. Wednesday, April 5, 2017.

Fixes #4663.
2017-05-16 16:58:22 -07:00
Tim Abbott
7bee733565 requirements: Upgrade to the latest Django release. 2017-05-16 15:56:16 -07:00
Tim Abbott
feda8cd012 css: Fix missing top border in PM recipient bars.
Technically, they were also missing on stream message recipient bars,
but the difference was invisible.
2017-05-16 14:48:37 -07:00
Tim Abbott
d1fb4aa130 css: Fix missing right border in PM recipient bars. 2017-05-16 14:48:37 -07:00
Tim Abbott
5048edc25c css: Decrease vertical space at top of feed.
This is system unfortunately has a rather complicated calculation to
compute the offsets correctly, but the net effect here is that the top
section of the Zulip window is much more space-efficient.

Shrinking the tab bar underpadding, part of this change, fixes #4444.

We only need the underpadding to be as tall as the space above the
floating recipient bar, which is definitely less than 10px, so I don't
anticipate regressions caused by this.
2017-05-16 14:48:34 -07:00
Tim Abbott
00c7f7d42f Remove date separators from the top of the message feed.
Now that we have the date visible in the recipient rows, we no longer
need a top-of-feed date separator.

Fixes #4581.
2017-05-16 14:47:04 -07:00
Tim Abbott
575dde3881 help: Add link to new organization getting-started guide. 2017-05-16 13:52:58 -07:00
Tim Abbott
f15e134bb0 apps: Update link to point to future Zulip iOS app ID.
Previously, this was linked to the now-removed old Dropbox iOS app for
Zulip.  The link won't work for a few more days, but we're just
waiting on app store approval and know the ID, at least.

Fixes #3267.
2017-05-16 13:45:02 -07:00
Harshit Bansal
0d28d5d808 build_emoji: Fix the spritesheet CSS generation code.
Modify the spritesheet generation code to account for the differences
between emoji_map.json and iamcal's dataset. Due to the differences
between the two mappings, some emojis like 1️⃣, 2️⃣ etc were not
getting rendered properly in the two emoji pickers where we are using
the iamcal's spritesheets for rendering them. This was so because there
was no CSS class corresponding to the codepoints of these emojis(as
mapped using emoji_map.json) in our spritesheet CSS(generated using
iamcal's dataset).

Fixes: #4775.
2017-05-16 13:06:12 -07:00
Harshit Bansal
0667297c6e build_emoji: Fix the coloring of the white emojis.
Fix the coloring of the white emojis to match that of the images
in the iamcal's spritesheets.
2017-05-16 13:06:12 -07:00
Tim Abbott
0b2388bda9 push_notifications: Remove DeviceTokenType logic.
The syntax wasn't valid on Python 3.5, and the new code is somewhat
more readable anyway.
2017-05-16 12:26:55 -07:00
Tim Abbott
9d63a5ab3a push_notification: Delete obsolete DBX_IOS_APP_ID code.
I'm not sure that this was ever actually used, but it's definitely
just clutter for Zulip today.
2017-05-16 12:26:55 -07:00
Umair Khan
286f9a40e7 push_notifications: Bring file to 100% coverage. 2017-05-16 12:26:55 -07:00
Umair Khan
fa5c66c439 push_notifications: Add num_push_devices_for_user tests. 2017-05-16 12:26:55 -07:00
Umair Khan
88f5d29e19 push_notifications: Add send_to_push_bouncer tests. 2017-05-16 12:26:55 -07:00
Umair Khan
af27ad607a push_notifications: Add handle_push_notification tests. 2017-05-16 12:26:55 -07:00
Umair Khan
8a6498f55d push_notifications: Create BouncerTestCase.
Adds bounce_request method to simulate a bounce.
2017-05-16 12:26:55 -07:00
Umair Khan
5907877038 push_notifications: Add test for send_notifications_to_bouncer. 2017-05-16 12:26:55 -07:00
Umair Khan
fab4249893 push_notifications: Add get_gcm_payload tests. 2017-05-16 12:26:55 -07:00
Umair Khan
136a950041 push_notifications: Add test for APNs payload. 2017-05-16 12:26:55 -07:00
Umair Khan
47d0f7d996 push_notifications: Add tests for get_alert_from_message. 2017-05-16 12:26:55 -07:00
Umair Khan
df0d29aaff push_notifications: Add response_listener tests. 2017-05-16 12:26:55 -07:00
Umair Khan
fc0b9358e7 handle_push_notification: Remove the if condition.
'if apple_devices or android_devices' doesn't servce any purpose.
2017-05-16 12:26:55 -07:00
Umair Khan
c4e5b75ead push_notification: Push data from Zilencer. 2017-05-16 12:26:55 -07:00
Umair Khan
ab411ab7b3 push_notifications: Delete remote server tokens in APNs response. 2017-05-16 12:26:55 -07:00
Umair Khan
33332539df send_android_push_notification: Delete correct tokens.
Now this function will delete tokens from RemotePushDeviceToken if it
is running on notification bouncer or PushDeviceToken if it is running
on a server which doesn't use notification bouncer.
2017-05-16 12:26:55 -07:00
Umair Khan
4a864c7515 push_notification: Send data to notification bouncer. 2017-05-16 12:26:55 -07:00
Umair Khan
4e2a6834d8 authenticated_rest_api_view: Use is_remote_server.
Using is_remote_server is more readable and future-proof since
it provides a level of abstraction.
2017-05-16 12:26:55 -07:00
Steve Howell
e6cc0ffcdd Eliminate PMs to non-subscribers when creating streams.
This should make stream creation relatively fast again, since we
will no longer send O(N) PMs out to tell folks the stream was
created.
2017-05-16 10:43:27 -07:00
Steve Howell
b9cc3a16a4 minor css: Add margin above "Announce stream".
The margin makes it slightly more clear that "Anyone can join"
vs. "People must be invited" is the main decision to make here.
2017-05-16 10:43:27 -07:00
Steve Howell
22c1231222 Hide "Announce stream" if realm has no "announce" stream.
When you create a stream, there was always an "Announce stream"
option that would be enabled for public streams.

We are about to make it so that we never send PMs to announce
new streams to folks, so the only mechanism will be sending a message
to the realm's notification stream.  If a realm has no notifications
stream, the decision is moot, so we hide the option.
2017-05-16 10:43:27 -07:00
Harshit Bansal
c549dea9ac bugdown: Fix the regex used for unicode emoji matching.
The regex we were using didn't cover all the unicode blocks
to which our emojis belong. This commit fixes the regex to
include all the unicode blocks and also updates the
corresponding JS regex in marked.js.

Fixes: #3460.
2017-05-16 09:05:42 -07:00
Harshit Bansal
f8824ea623 bugdown: Fix the unicode_emoji_to_codepoint() function.
Unicode codepoints are of minimum length 4, padded with extra
zeroes if the length is less than 4. This commit fixes the
`unicode_emoji_to_codepoint()` to ensure that the codepoint
it generates are of correct length.
2017-05-16 09:05:42 -07:00
Steve Howell
c8dd056ac5 Extract you_were_just_subscribed_message(). 2017-05-16 09:01:00 -07:00
Steve Howell
bbd8c1c49b Do not send PMs to subscribers when creating streams.
When we create a stream, we usually send a welcome message on the
stream itself as well as an announcement on the announcement stream,
but we no longer PM the individual users.  Hopefully this will be
more pleasant for users (less spammy), and it also will make creating a
stream a lot faster.

We still send notifications when we add subscribers to an existing
stream.
2017-05-16 08:58:17 -07:00
Tim Abbott
1c03ec2e23 help: Add a detailed article on creating a new Zulip organization.
Thanks to Rishi Gupta, James Rowan, and many others for their work on
this.

This replaces most of the content in prod-customize.md; we'll
deduplicate soon.
2017-05-16 00:29:23 -07:00
Tim Abbott
61d9f5647e compare: Clean up comparison chart entries. 2017-05-15 23:23:27 -07:00
Tim Abbott
8f488eb4d6 compare: Lower font weight for Xs. 2017-05-15 23:23:26 -07:00
Tim Abbott
5c745bf72a landing: Fixup styling of /compare/ page. 2017-05-15 22:21:04 -07:00
Tim Abbott
fb2647397b landing: Fix navigation to not link to registration. 2017-05-15 21:56:02 -07:00
Tim Abbott
847f469cf2 subdomains: Toggle various links with SUBDOMAINS_HOMEPAGE. 2017-05-15 21:54:35 -07:00
Tim Abbott
1d1b0894a3 zulip_ops: Add logrotate configuration from main zulip. 2017-05-15 21:54:35 -07:00
Tim Abbott
e049ea01b1 puppet: Update munin configuration to work with modern munin. 2017-05-15 21:49:53 -07:00
Tim Abbott
6871c227cd puppet: Add missing restarts of Nagios on config updates. 2017-05-15 21:49:53 -07:00
Tim Abbott
f4a049110f navigate: Fix incorrect reference to narrow.stream().
This was renamed to narrow_state.stream() recently.
2017-05-15 21:07:00 -07:00
Tim Abbott
a0006e4328 design: Rename @-mentions filter to Mentions.
This should make the design a bit more consistent and usable.
2017-05-15 20:55:27 -07:00
Tim Abbott
2007144c23 css: Fix arrangement of streams in new user invitations.
Previously, they were line-wrapped in an ugly fashion.
2017-05-15 20:43:24 -07:00
Steve Howell
e2732dabf3 Send welcome messages as part of /create_realm flow.
We now pre-populate the streams in DEFAULT_NEW_REALM_STREAMS
(social/general/zulip, unless somebody changes settings.py) with
welcome messages.  This makes the streams appear to be active
right away, and it also gives the Zulip realm less of a
blank-slate feeling when you create it.

This change only affects the normal web-based create-realm flow.
It doesn't impact the management commands for creating realms
or setting default streams.
2017-05-15 20:38:08 -07:00
digi0ps
729bd6af12 settings: Enter now submits the data in Default stream settings.
Fixes #4232.
2017-05-15 20:36:18 -07:00
digi0ps
6f7b973d3b settings: Fix error handler for Default Streams.
Updates the error handler code to be consistent with how errors
are displayed everywhere else.
2017-05-15 20:34:45 -07:00
digi0ps
63587d6b70 settings: Add submit button for Default Stream form. 2017-05-15 20:34:17 -07:00
Tim Abbott
df5a0e7c92 hotkeys: Simplify logic for checking for subscriptions page. 2017-05-15 20:28:56 -07:00
Cynthia Lin
4cc33b6173 hotkeys: Disable enter hotkey while Streams menu is open.
Prevents compose box from opening and potentially sending a message.
Fixes #2412
2017-05-15 20:28:56 -07:00
Eeshan Garg
21e0db03e1 webhooks/appfollow: Migrate docs to Markdown. 2017-05-15 20:14:23 -07:00
Eeshan Garg
0b5711aa7e webhooks/airbrake: Migrate docs to Markdown. 2017-05-15 20:14:23 -07:00
Eeshan Garg
7227f488c8 webhooks: Add support for a GitHub push event deleting a branch.
Fixes: #4742.
2017-05-16 00:11:20 -02:30
Tim Abbott
0b46be2fed Avoid UserActivity logging for RemoteZulipServer requests.
We had a somewhat messy bug where we were sending invalid entries to
the UserActivity queue when using the push notification bouncer.
2017-05-15 17:15:01 -07:00
Tim Abbott
c7d2caab6e zilencer: Add auto_now to RemoteZulipServer.last_updated.
This should simplify the logic needed to create one of these.
2017-05-15 17:04:33 -07:00
Brock Whittaker
07ecf971c6 Fix accounts_home and login to display no-password correctly.
This fixes the /register/ (accounts_home) and /login/ pages to not
display the login form if login isn’t allowed at the organization level.
2017-05-15 15:49:02 -07:00
Steve Howell
c7f710b8d4 muting.js: Track muted streams using stream id.
This should prevent some glitches with stream rename events.
2017-05-15 14:47:41 -07:00
Steve Howell
8eb9723283 stream_list: Call update_streams_sidebar() on renames.
If you rename a stream, call update_streams_sidebar() to
make sure we redraw the active stream correctly.
2017-05-15 14:47:41 -07:00
Steve Howell
76f68e9836 Fix buggy update_streams_sidebar().
If you were narrowed to an unpinned stream, and then pinned it,
we were mostly redrawing the sidebar correctly, but we weren't
setting the active-filter class.  Now we accomplish this by
calling maybe_activate_stream_item(), which also reduces some
code duplication.  (The new code introduces a bit of extra logic
to do `stream_li.addClass('active-filter')`.
2017-05-15 14:47:41 -07:00
Steve Howell
5b6bd6767b refactor: Extract stream_list.maybe_activate_stream_item(). 2017-05-15 14:47:41 -07:00
Steve Howell
1a11042fdf refactor: Use stream id more in topic_list.js. 2017-05-15 14:47:41 -07:00
Steve Howell
2e39d48626 Add stream_data.get_recent_topics_for_id(). 2017-05-15 14:47:41 -07:00
Steve Howell
762194f98d Add stream_data.id_is_subscribed().
We use this function in stream_list.js.
2017-05-15 14:47:41 -07:00
Steve Howell
efb35afeb7 Track recent topics (and active streams) using stream id.
This commit changes the key for recent_topics to be a
stream id.  For streams that have been renamed, we will now
get accurate data on recent topics and active streams as
long as stream_data.get_stream_id(stream_name) returns a
valid value.
2017-05-15 14:47:41 -07:00
Steve Howell
5d33d02235 Track unread counts using stream_id. 2017-05-15 14:47:41 -07:00
Steve Howell
c125ba1d08 Fix how we find if streams are muted.
This commit changes stream_data.in_home_view() to
take a stream_id parameter, which will make it more
robust to stream name changes.

This fixes a bug.  Now when an admin renames a stream
you are looking at, it will correctly show itself to
be un-muted. (Even with this fix, though, the stream
appears to be inactive.)

Some callers still do lookups by name, and they will
call name_in_home_view() for now, which we can
hopefully deprecate over time.
2017-05-15 14:47:41 -07:00
Steve Howell
d3a7aa3a37 Have get_stream_li() take a stream_id.
Rather than having get_stream_li() look up stream id using
stream name, we force the callers to pass in the stream id.

This adds an extra line to most of the callers for now, but
this will eventually change as we fix some of the callers to
have their callers pass in stream_id.

In places where we now call stream_data.get_stream_id() to
get the stream id, we will be more resilient toward stream
renamings, at least until the next reload, since
stream_data.get_stream_id() can resolve old names that
are stored when we process stream-rename events.
2017-05-15 14:47:41 -07:00
Steve Howell
a48419310e Simplify get_filter_li() and get_stream_li().
We no longer have get_stream_li() delegate to get_filter_li(),
which simplifies the logic in get_filter_li() and makes
get_stream_li() more direct.

We also move the two functions closer to each other in the file.
2017-05-15 14:47:41 -07:00
Steve Howell
292b0ac64d Extract set_stream_unread_count. 2017-05-15 14:47:41 -07:00
Steve Howell
cfdf256c62 refactor: Call get_stream_li() in a few places.
This is a step toward simplifying get_filter_li().
2017-05-15 14:47:41 -07:00
Tim Abbott
400845d1d5 docs: Remove shortcuts list documentation of drafts navigation.
These are fairly intuitive given how navigation works elsewhere, and
not having them here helps avoid things feeling intimidating.
2017-05-15 13:42:30 -07:00
Tim Abbott
feeb648e00 hotkeys: Swap Drafts with Menus.
It seems good to have "Show keyboard shortcuts" be last.
2017-05-15 13:42:11 -07:00
Cynthia Lin
36b66cda74 user docs: Update keyboard shortcuts docs with Drafts modal shortcuts. 2017-05-15 13:32:21 -07:00
Cynthia Lin
934bae5232 user docs: Add user guide for *View and edit your message drafts*.
Fixes #4335.
2017-05-15 13:32:18 -07:00
Aditya Bansal
1769a444de Remove unnecessary ignore files.
In this commit we remove user_sidebar_actions.handlebars from
IGNORE_FILES as well remove the check for files to be in a
IGNORE list thus reaching 100% 4 space indent checking for
handlebar templates.

Fixes: #1661.
2017-05-15 11:51:21 -07:00
Aditya Bansal
debcf507bd Clean organization-settings-admin to use 4 space indents. 2017-05-15 11:51:21 -07:00
Aditya Bansal
8530997542 Clean default-streams-list-admin to use 4 space indents. 2017-05-15 11:51:21 -07:00
Cynthia Lin
1bea4da0f4 org settings: Fix minor styling inconsistencies.
Fixes #4789.
2017-05-15 11:35:58 -07:00
Tim Abbott
44113d6436 docs: Update link to python-social-auth. 2017-05-13 23:00:50 -07:00
Tim Abbott
97abaae9af home: Remove now-unnecessary page_params_core_fields duplication.
Also, we update the documentation to make the overall system a bit
clearer.

Fixes #4628.
2017-05-13 22:58:18 -07:00
Tim Abbott
157e0623f8 5xx: Remove hardcoded twitter/email contacts from nginx 500 page.
There's no correct contact that we can list here unconditionally;
previously, we had people emailing zulip-devel@ because their server
was misconfigured.

Addresses #696 enough that it's no longer a priority issue.
2017-05-13 22:44:34 -07:00
Tim Abbott
3fd1943eb6 requirements: Move api dependency out of common.txt.
This is preparation for using `pip compile` to help automate our
requirements files; `pip compile` does not support relative paths.
2017-05-13 22:13:00 -07:00
Tim Abbott
864bc99aeb requirements: Move common includes to py2/py3, not dev/prod.
This is a nonfunctional refactor of how the common.txt requirements
are included.  It is preparation for a new model for freezing our
recursive dependencies based on `pip compile`.
2017-05-13 22:09:42 -07:00
Steve Howell
252d0a6e15 Use stream_data.get_name() in narrow_state.stream().
Using get_name() is more robust for stream name changes.  This
fixes, for example, the situation where you narrow to a stream,
edit it via the sidebar, and then close the modal, and the message
redraw logic thinks you have unsubscribed.

Fixes #4686.
2017-05-13 21:59:08 -07:00
Steve Howell
8b78f3f133 Look up old stream names in stream_data.get_name().
This change fixes a few small things related to stream
renames, such as what happens if you hit the back button
to go to a narrow where the stream had been renamed.  You
will now get the correct behavior in terms of filtering
and searching.  Unfortunately, this will only last until
you reload.
2017-05-13 21:59:08 -07:00
Steve Howell
191741a382 Use stream ids to filter messages in client-side narrows.
We now use stream ids to filter messages in narrowing
situations, instead of doing stream name comparisons.

This partially fixes certain stream-renaming scenarios, since
we will be able to match the stream id for an out-of-date
stream operand, but it doesn't fix some other stuff, such
as the query that the server gets.
2017-05-13 21:59:07 -07:00
Steve Howell
8ecfda9344 stream_data: Remember old stream names.
This is not a user-facing change, but it starts us down the
path to having the JS client be able to look up old stream
names for situations like people clicking old external links
or for live-update scenarios.
2017-05-13 21:58:37 -07:00
Tim Abbott
f36000d670 docs: Fix last reference to old fixtures directory structure. 2017-05-13 21:39:12 -07:00
Eeshan Garg
762850876b integration-guide: Replace references to old style fixture names.
The integration-guide has now been updated to reflect the recent
decision to rename webhook fixtures from
<webhook_name>/fixtures/<webhook_name>_<event_type>.json to
<webhook_name>/fixtures/<event_type>.json.
2017-05-13 20:22:40 -02:30
Eeshan Garg
eb229dd40e webhook-walkthrough: Replace references to old style fixture names.
The webhook-walkthrough has now been updated to reflect the recent
decision to rename webhook fixtures from
<webhook_name>/fixtures/<webhook_name>_<event_type>.json to
<webhook_name>/fixtures/<event_type>.json.
2017-05-13 20:13:35 -02:30
Eeshan Garg
597db11a98 webhooks: Rename webhook fixtures to only include event type.
All webhook fixtures have now been renamed from
<webhook_name>/fixtures/<webhook_name>_<event_type>.json to
<webhook_name>/fixtures/<event_type>.json.
2017-05-13 20:07:40 -02:30
Tim Abbott
acb3c1e7ff test_templates: Fix errors from compare.html template. 2017-05-13 14:57:06 -07:00
Eeshan Garg
10dcc99983 zerver/decorators: Log all exceptions raised in api_key_only_webhook_view.
Fixes #4742.
2017-05-13 14:53:47 -07:00
Tim Abbott
286bbff800 left-sidebar: Change color of STREAMS label on hover. 2017-05-13 14:41:58 -07:00
derAnfaenger
45a9b657c7 Refactor left sidebar topic cursor css.
This commit addresses to issues with the left sidebar:
The cursor flickering when hovering over topics, and
the cursor not becoming a pointer when resting just right
of a topic's name (in a clickable area).

This is a follow-up to #4675.
2017-05-13 14:41:48 -07:00
Tim Abbott
d6059d0d9a landing: Add template containing comparison checkmarks.
Can be added to the landing pages via:
+    {% include 'zerver/compare.html' %}
+

I'm avoiding adding that include into the landing pages until we have
time to do a bit of tweaking of the styling to integrate better into
/hello/ (primarily color-wise).

Most of the work for this was done by Brock, huge thanks to him!
2017-05-13 14:32:24 -07:00
Tim Abbott
51978d0f89 tests: Fix failing login tests.
Apparently I missed these when updating
4d2bb0dec8.
2017-05-13 13:05:15 -07:00
Tim Abbott
4d2bb0dec8 templates: Clean up visuals for account-not-found SSO flow.
Also, clarify that the account that isn't found is your Zulip account,
not a GitHub/Google Oauth account.
2017-05-13 12:46:05 -07:00
Tim Abbott
0b5954feee Increase initial messages on user creation from 100 to 1000.
This makes the new user experience in an active community like
chat.zulip.org substantially nicer, since the new user will have the
same level of initial messages to populate topics (etc.) as an
existing user who is caught up.

Without this, there was an undue level of fading-for-inactivity in the
default streams.
2017-05-13 12:16:05 -07:00
rht
34ffda9a1e docs: Fix a bunch of documentation build warnings.
This helps clean unnecessary warnings out of Zulip's Travis CI output.
2017-05-13 10:09:20 -07:00
hackerkid
cf15a7b561 presence.js: Make get_status return active for logged in user. 2017-05-12 14:28:23 -07:00
Tim Abbott
ab3f55408d settings: Document how to set EXTERNAL_HOST to include a port number.
Also, make sure that ALLOWED_HOSTS is correct in the case that a port
number is included.
2017-05-12 14:27:29 -07:00
Abhijeet Kaur
0b7d138871 settings: Make description textarea readonly for non-admin users.
Fixes #4754.
2017-05-12 14:16:43 -07:00
Tim Abbott
25516c6949 models: Update comment explaining order of display recipients. 2017-05-12 13:53:06 -07:00
Tim Abbott
72abd4f12d mentions: Fix subject line and sender for missed-message mentions.
This fixes 2 issues:
* The term "@-mentioned" is simplified to "mentioned".
* We would incorrectly list other people who sent context messages as
  among the people who mentioned you.
2017-05-12 13:50:25 -07:00
James Rowan
0facaa0797 Changes sender and subject lines for missed message emails.
Now, in the event of messages between two other members of a huddle,
the missed message emails are threaded in "Group PMs with name1 and
name2" and not in separate threads by sender.

Also, now the order of recipients in get_display_recipient consistent
with the order of names that appears in the list of personal messages
on the left sidebar.

Fixes most of #4553.
2017-05-12 13:29:43 -07:00
Tim Abbott
f25d7dd721 settings: Fix spelled of muted topics message. 2017-05-12 12:38:29 -07:00
Steve Howell
a0fab6842c Improve error handling in get_action_menu_menu_items(). 2017-05-12 12:25:03 -07:00
Aditya Bansal
33f3d773b0 Clean user-list-admin to use 4 space indents. 2017-05-12 12:23:01 -07:00
Aditya Bansal
0c39a45d72 Clean bot-list-admin to use 4 space indents. 2017-05-12 12:23:01 -07:00
Steve Howell
f0b30b57ca modals: Make error reports more specific.
We now give a more specific error message when something goes
wrong in closing a modal.
2017-05-12 08:27:25 -07:00
Tim Abbott
13a37f74a1 users: Ban names shorter than 3 characters.
The empty string is not a reasonable name.
2017-05-11 19:21:51 -07:00
Cory Lynch
08f1c86041 Make reaction picker case-insensitive.
The search bar for picking message reactions now is case-insensitive,
since that's a better user experience, and there isn't a clear use
case for capital letters in emoji names.

Fixes #4666.
2017-05-11 19:10:21 -07:00
Cory Lynch
b1bfe9f42e Add migration to force lowercase existing realm emoji.
Since realm emoji are now required to be lowercase,
an appropriate migration was added to retroactively
fix any emoji that might have contained uppercase
letters.

Also, the validator on the model was changed to
reject uppercase letters.
2017-05-11 19:10:21 -07:00
Cory Lynch
68e5898a07 emoji.py: Add restriction that realm emoji must be lowercase.
Raises error if emoji name has an uppercase letter in it.
2017-05-11 19:10:21 -07:00
Tejas Kasetty
9b9c323314 emoji picker: Move cursor to end of filter string when focusing.
This is a much less annoying behavior than the Chrome browser default.

Explanatory comment added by tabbott, thanks to Steve Howell for the
research.

Fixes #4604.
2017-05-11 18:54:44 -07:00
Joshua Pan
235d06e7e5 docs: Correct bullet point formatting in keyboard shortcuts. 2017-05-11 18:46:24 -07:00
Brock Whittaker
f1a7db2503 Add placeholders to all empty lists.
This adds placeholders that state that the lists are empty.
2017-05-11 17:49:27 -07:00
Brock Whittaker
e294035c93 Fix table display.
This fixes the way that tables display across the settings page,
so that the buttons shouldn't collapse to the second line anymore.
2017-05-11 17:49:26 -07:00
Brock Whittaker
8559acec1d Clean up settings overlay "Your Account" tab display.
This enforces a max-width of 1024px on the #settings overlay.

This commit also cleans up the "Your Account" tab to display
correctly without the avatar bleeding over to the next line.
2017-05-11 17:49:26 -07:00
Brock Whittaker
478011c0af Remove headers from templates. 2017-05-11 17:49:26 -07:00
Brock Whittaker
f95021d419 Add settings sections to header.
This adds the settings section that you are in to the page header.
2017-05-11 17:49:26 -07:00
Brock Whittaker
6e7305f784 js: Implement DynamicText class.
This implements the DynamicText class for resizing of text to fit the
parent node.
2017-05-11 17:23:53 -07:00
Rishi Gupta
0ce04556bf CSS: Change color of PMs from yellow to blue-grey. 2017-05-11 16:18:39 -07:00
Steve Howell
d415d4cf11 Add error handling in watch_manual_resize().
We now explicitly complain if a caller passes in a bad
selector to this function and return undefined.
2017-05-11 15:45:47 -07:00
Tim Abbott
35a5ca411a emoji: Fix scaling of realm emoji in reactions.
Fixes #4762.
2017-05-11 14:40:05 -07:00
Tim Abbott
eb6af282fb login: Shrink font size of organization name. 2017-05-11 14:26:06 -07:00
Tim Abbott
6eada74bfe portico: Fix exception if no realm description is set.
This was caught via Casper tests, which I regret not running.
2017-05-11 14:23:46 -07:00
Tim Abbott
223624be25 settings: Add support for longer, markdown-powered realm descriptions.
This makes it possible to create much prettier login pages.

Further work on styling may be necessary.
2017-05-11 13:59:46 -07:00
Umair Khan
e649c05aed views.py: Create validator for remote server. 2017-05-11 12:04:16 -07:00
Umair Khan
329b377e6a push_notification: Add uses_notification_bouncer().
This function abstracts the logic to ascertain if we are using
notification bouncer service or not. Makes our code more
maintainable.
2017-05-11 12:04:16 -07:00
Umair Khan
112a67097b push_notifications: Don't get alert message.
Now we set the alert message in the payload functions for both GCM and APNs so
no need to get it here.
2017-05-11 12:04:16 -07:00
Umair Khan
3c32bc6d8a push_notification: Create get_gcm_payload. 2017-05-11 12:04:16 -07:00
Umair Khan
d90774b9db push_notifications: Create get_apns_payload.
This function creates the payload that we will send to APNs.
2017-05-11 12:04:16 -07:00
Umair Khan
5ff7fdf83a push_notification: Create get_alert_from_message.
This function returns the alert shown by iOS or Android device.
2017-05-11 12:04:16 -07:00
Umair Khan
10ed47156d api_auth: Use is_remote_server. 2017-05-11 12:02:26 -07:00
Umair Khan
faf190ff34 validate_api_key: Use is_remote_server. 2017-05-11 12:02:26 -07:00
Umair Khan
252fa53816 api: Add is_remote_server().
This function abstracts the logic to ascertain the source of API
auth request.
2017-05-11 12:02:26 -07:00
Tim Abbott
2c64626e7a mobile: Disable tutorial on mobile clients. 2017-05-11 11:01:56 -07:00
Steve Howell
d7813ee6b3 reactions: Remove unneeded message_store.get() calls.
Both callers to get_user_list_for_message_reactions() already
had a message object, so there was no need to pass in an id
just to fetch it from message_store again, so now the first
parameter is message, not message_id.
2017-05-11 09:39:17 -07:00
Steve Howell
87f5c22593 Simplify how we find the current user's emoji reactions.
This adds the current_user_has_reacted_to_emoji() helper.

This new helper is easier to use and slightly more efficient
than calling get_user_list_for_message_reaction() and then
indexOf().

This also replaces one call to get_user_list_for_message_reaction()
with a list of user_ids that we already had locally.

The node tests were improved a bit here, including a minor
whitespace fixup.
2017-05-11 09:39:17 -07:00
Tim Abbott
3bf5c647d9 css: Remove black background for signin logo. 2017-05-11 09:00:23 -07:00
rht
7ad6a66340 requirements: Remove redundant library list.
The line `-r common.txt` can be found in dev.txt and prod.txt

This should speed up the build process by 2-3s, in addition to the speed
up from not having to prepare a python2 venv.
2017-05-11 08:52:42 -07:00
Steve Howell
958ed20a0f Only render one stream at a time for editing.
We used to render the subscriptions_settings template for every
stream when you loaded "Manage Streams," which can be very slow
for a big realm.  Now we only render the right pane on demand.
2017-05-11 08:46:52 -07:00
Steve Howell
a9031fe7b3 Fix some bugs for changing stream privacy.
The function stream_data.add_admin_options() got removed as
part of a somewhat recent fix.  This caused a console error, and
the modal would not go away.

We now call the new stream_data.update_calculated_fields().

This commit only addresses the recent regression.  We still have
the known issue that public/private changes do not get
live-updated for other users.
2017-05-11 08:46:52 -07:00
Umair Khan
dc2a9a4c5b github: Add sign up button on registration page. 2017-05-10 17:49:08 -07:00
Umair Khan
d56db0a3b4 auth.py: Add confirmation handlers for signup.
These handlers will kick into action when is_signup is False. In case
the account exists, the user will be logged in, otherwise, user will
be asked if they want to proceed to registration.
2017-05-10 17:20:34 -07:00
Umair Khan
11426a2cec log_into_subdomain: User should be None in signup. 2017-05-10 17:20:34 -07:00
Tim Abbott
5019b53492 auth: Pass is_signup option around. 2017-05-10 17:20:34 -07:00
Tim Abbott
ce3974b40e auth: add is_signup option to login_or_register_remote_user. 2017-05-10 17:20:34 -07:00
hackerkid
9aaf175ec6 Move add new default stream box to top.
Fixes #4734.
2017-05-10 16:56:30 -07:00
Brock Whittaker
f651c7fb18 user-profile: Add mobile-responsive styling.
This changes the styling of the user profile popup to be responsive
to mobile devices. In this case it is converted to a modal form using
flex to center it on devices with screen sizes under 768px in width.

Fixes #4669.
2017-05-10 16:49:42 -07:00
Tejas Kasetty
5dd5c84854 Add support for emoji picker hotkeys in compose context.
This is a follow-up to merging the compose and reactions emoji
pickers.  The logic for what happens when the user picks an emoji via
the hotkeys (i.e. hits `enter`) was still attempting to add a reaction
to the currently selected message unconditionally.

This commit adds a check in the two `enter` key code paths, and does
the correct thing in each case.

Fixes #4736.
2017-05-10 16:26:58 -07:00
Brock Whittaker
52059d21a4 product-pages: Fix broken click target on .hamburger.
The click target was still for #hamburger even though it has since
been changed to .hamburger. This fixes the selectors to make it work
with the new className declaration over ID.
2017-05-10 14:56:36 -07:00
Tim Abbott
e8eaec0a18 mypy: Fix various errors caught by removing cache_with_key. 2017-05-10 14:37:20 -07:00
Tim Abbott
e55b4b0d43 invites: Fix buggy access to non-existant user_profile.name. 2017-05-10 14:31:24 -07:00
Tim Abbott
a85c066722 confirmation: Fix race with invite and email change. 2017-05-10 14:31:24 -07:00
Tim Abbott
df8a577aa6 zephyr_mirror: Include URL for mirroring server. 2017-05-10 11:54:09 -07:00
Tim Abbott
b595ec6fbe zephyr_mirror: Fix buggy zephyr_mirror_backend import. 2017-05-10 11:52:34 -07:00
Tim Abbott
4c572ea296 zmirror-renew-kerberos: Clean up hardcoding of user ID. 2017-05-10 11:52:34 -07:00
Tim Abbott
66e52037c0 zephyr_mirror: Avoid transmitting null characters to server. 2017-05-10 11:52:34 -07:00
Tim Abbott
87f06fd837 zephyr_mirror: Add support for discuss-format messages. 2017-05-10 11:52:34 -07:00
Tim Abbott
a0a50d410c test_docs: Add tests to ensure all integrations present. 2017-05-10 11:30:32 -07:00
Tim Abbott
a3ddd94aa3 integrations: Remove unnecessary email_integration_enabled.
Previously, we were ending up with 2 copies of the email integration
in there.
2017-05-10 11:24:25 -07:00
Tim Abbott
f94193c231 integrations: Remove unnecessary conditional. 2017-05-10 11:21:10 -07:00
Tim Abbott
248785e66e integrations: Fix missing links to non-webhook integrations.
Apparently help_content was attached to the wrong class.

Fixes #4744.
2017-05-10 11:17:56 -07:00
Tim Abbott
232592cc9f test_sessions: Extends tests to reach 100% coverage of sessions.py.
Fixes #3980.
2017-05-10 10:12:21 -07:00
andrewallen00
53f1f75fcb Add tests for zerver/lib/sessions.py. 2017-05-10 10:12:14 -07:00
Steve Howell
f60a829b4d Remove lightbox.is_open property.
Outside of lightbox.js, we now use modals.lightbox_open() to
detect that the lightbox modal is open.
2017-05-10 09:46:21 -07:00
Steve Howell
1d7f93e550 Avoid re-opening the lightbox.
If the lightbox is already open, don't re-open it.
2017-05-10 09:46:21 -07:00
Tim Abbott
0e05f3f4ee emails: Remove pre-email-migration scheduled jobs.
This fixes an issue introduced when we migrated the format of all of
our emails, which caused any old ScheduledJob rows to be corrupted.
2017-05-10 09:45:40 -07:00
Tim Abbott
c2a11655ef css: Decrease stream padding in left sidebar. 2017-05-10 09:45:40 -07:00
Tim Abbott
9f7236eec1 message: Remove unused old gravatar_hash field from message dicts.
This was deprecated and replaced some 4 years ago.
2017-05-09 22:33:27 -07:00
Tim Abbott
e3505bd5ae avatar: Fix memcached query loop fetching messages.
This fixes a major performance issue, where we would fetch
user_profile objects inside a code path that had already bulk-fetched
the necessary user objects.

Like the similar related changes we just made, the fix is to marshall
and pass the data into the avatar library directly.
2017-05-09 22:33:27 -07:00
Tim Abbott
0990246289 avatar: Fix memcached query loop fetching bots.
Similar to the related issue with users, the new avatar storage had
accidentally added database queries in a loop to this code path.
2017-05-09 22:33:27 -07:00
Tim Abbott
8e47dc73bd avatar: Fix loop doing database queries in register.
Due to the refactoring of the avatar URL codepath that added realm IDs
to the URLs, we ended up calling `get_user_profile_by_email` inside
`get_avatar_url`, which in turns was called in a loop over all users
in a realm.

Needless to say, this resulted in a significant performance problem.

We fix this issue by passing in the data needed to compute the avatar
URL, rather than looking it up by email address.
2017-05-09 22:33:27 -07:00
Tim Abbott
676d4f32fc avatar_url: Fix unnecessary database query.
If we have a user_profile object, there's no reason to fetch it again
from memcached.
2017-05-09 22:33:27 -07:00
Tim Abbott
c8b0ac0a05 avatar_hash: Extract user_avatar_path_from_ids. 2017-05-09 22:31:24 -07:00
Tim Abbott
e94586adb4 puppet: Fix path to events_deliver_enqueued_emails.log. 2017-05-09 22:29:58 -07:00
Tim Abbott
c21d336bfe css: Use the Zulip static asset pipeline for emoji sprite sheet CSS.
This should be a nonfunctional change in most cases; the main benefit
should be preventing caching issues if/when our sprite sheets change.
2017-05-09 19:45:57 -07:00
Tim Abbott
3d5350408b css: Fix vertical alignment of global filter counts.. 2017-05-09 19:17:33 -07:00
Tim Abbott
60a81fef43 design: Restore font color in left sidebar to #333.
This fixes a major complaint with the left sidebar styling.
2017-05-09 19:00:46 -07:00
Brock Whittaker
7dbf0c8811 Normalize left and right sidebar font size.
This normalizes the left and right sidebar font size to be 0.89rem.
2017-05-09 18:54:10 -07:00
Brock Whittaker
242eb9b346 portico-sidebar: Fix sidebar logo to be current logo.
This fixes the sidebar logo to be the current zulip logo rather
than a mockup of a potential logo that was from the redesign.
2017-05-09 18:48:33 -07:00
Steve Howell
5c52495b64 Use modals.settings_open().
We now uses modals.settings_open() to check for the settings
modal being open, rather than doing a regex check on
windows.location.hash.
2017-05-09 18:44:08 -07:00
Steve Howell
37254c9031 Simplify ESC handling for modals.
Rather than checking every modal individually in hotkey.js for
handing the escape key, we now use the modals API:

    is_active: says whether any modal is open
    close_active: closes the active modal
2017-05-09 18:44:08 -07:00
Steve Howell
23b7be90c2 Fix console errors with closing settings.
We were mapping the escape key to fake-click a redundant
click handler when the settings pages were open.  This fix
lets the actual click handling work via modals.js, and it
lets keyboard handling directly calls modals.close_settings().
2017-05-09 18:44:08 -07:00
Tim Abbott
bd3e338c35 templates: Fix URL coverage for new files. 2017-05-09 18:42:24 -07:00
Tim Abbott
fc24a56fc5 test_docs: Fix expected text in /hello page. 2017-05-09 17:23:38 -07:00
Tim Abbott
df6dba9673 test_home: Fix expected text in /hello page. 2017-05-09 16:59:33 -07:00
Brock Whittaker
3fd3ae4199 Restyle /hello/ page.
This restyles the /hello/ page to be the new portico branding.
2017-05-09 16:31:57 -07:00
Brock Whittaker
a82a0d16d5 Add landing page assets.
This adds the required logos and other assets for the /hello/ page.
2017-05-09 15:26:45 -07:00
Tim Abbott
484adf1461 about: Update words of developer documentation. 2017-05-09 15:04:17 -07:00
Tim Abbott
6dd85a78ce about: Update to have slightly more current numbers. 2017-05-09 15:03:30 -07:00
Tim Abbott
937dcdde59 docs: Update which projects are marked complete in roadmap.
We need to do a more significant update soon, but this will at least
make things passable for now.
2017-05-09 14:34:53 -07:00
Tim Abbott
68be0edc67 Update changelog since the Zulip 1.5 release.
It's amazing how much we've done in the last few months.
2017-05-09 14:02:24 -07:00
Tim Abbott
2d97db3518 streams: Add endpoint for modifying properties of a single stream.
This is likely to be the more common endpoint for API clients like the
mobile apps to interact with when modifying streams.
2017-05-09 13:42:34 -07:00
kunall17
e087bc24f8 streams: Migrate stream property changes to new REST endpoint.
This is one of the last major endpoints that were still done in the
pre-REST style.

While we're at it, we change the endpoint to expect a stream ID, not a
stream name.
2017-05-09 13:39:23 -07:00
Rishi Gupta
a75af36039 stats: Change sort order of client labels to match default view. 2017-05-09 11:32:35 -07:00
Rishi Gupta
ee16abaf3b analytics: Fix sort function in views.sort_client_labels.
sort_client_labels sorts first by total, and then to ensure deterministic
outcomes, sorts (reverse) alphabetically by label.

Fixes regression introduced in 0c0e539.
2017-05-09 11:32:35 -07:00
Rohitt Vashishtha
0414ac6df5 bugdown: Convert GitHub image-preview urls to image urls.
This makes inline image previews work for links to image files' pages
on GitHub.

Fixes #4658.
2017-05-09 11:22:37 -07:00
Rohitt Vashishtha
5be7494ddf Remove duplicate connection-error message.
There's really no need for a separate user-visible error message for
get_messages vs. get_events.

Fixes #4703.
2017-05-09 11:13:27 -07:00
Steve Howell
94b7058743 Make local_echo an official feature.
This commit removes all references to feature_flags.local_echo.
It's been a core feature for about four years, so I think we
can safely say the experiment was successful.:)
2017-05-09 11:06:10 -07:00
Steve Howell
0a0f567aeb Split out markdown.js from echo.js.
The new module handles markdown rendering.

The code left behind in echo.js does local-echo kind of things
like reifying message ids.
2017-05-09 11:06:10 -07:00
Tomasz Kolek
61d5d41067 Add Slack importer bot. 2017-05-09 10:48:08 -07:00
Mahim Goyal
49fec57768 Add hotkey for narrowing to next unread topic.
Fixes: #4199.
2017-05-09 10:02:54 -07:00
Tim Abbott
40e43d8cba narrow: Remove unused by_conversation_and_time and by_id helpers.
Now that we just copy links to the clipboard, neither of these are
used.  (Actually, the narrow.by_id helper has been dead code for
years).
2017-05-09 09:59:37 -07:00
Mahim Goyal
a2adcfd7fc popovers: Add direct copy to clipboard link feature.
Change the onClick function of copy link of
conversation to actually copy the link to clipboard.

Fixes: #4621.
2017-05-09 09:59:23 -07:00
Mahim Goyal
6fe0728afa Return absolute URL from narrow.by_conversation_and_time_uri 2017-05-09 09:55:38 -07:00
Umair Khan
4971b7ff9f testing: Add errored tests to failed tests list.
Fixes: #4716.
2017-05-09 09:36:59 -07:00
Steve Howell
70d4ac93ce Add modals.info_overlay_open().
This also removes ui_state.js, since its last function
is now replaced by modals.info_overlay_open().
2017-05-09 09:19:27 -07:00
rht
00e057bf44 install-node: bypass nvm wrapper for faster node startup.
This fixes a significant performance issue with LaTeX rendering (and
other things that invoked node) where starting up node took a few
hundred milliseconds due to nvm initialization.

Tweaked by tabbott to avoid copying the node binary itself, instead
using a tiny wrapper script.

This is important primarily because it's possible a future version of
node will expect to find libraries/dependencies/etc. installed via NVM
at some path related to the path of the node binary itself, and that's
more guaranteed with this new model.

Fixes #4618.
2017-05-09 09:17:54 -07:00
Steve Howell
86a9283471 Update JS dependency configuration. 2017-05-08 22:04:56 -07:00
Steve Howell
742c55f514 Speed up key handling by adding modals.is_active().
The function modals.is_active() can see if modals are open
without having to look at the DOM.  This should make it snappier
to type in the compose box.  Even if the speedup is pretty minor,
not having to worry about jQuery slowness should make it easier
to diagnose future compose box issues.

The new function gets used in other places, too, where performance
isn't so much an issue.
2017-05-08 22:04:56 -07:00
Steve Howell
3c0ef6295f Enforce that only one modal can be open at any time. 2017-05-08 22:04:56 -07:00
Steve Howell
ddded59a6d Remove modals.set_close_handler(). 2017-05-08 22:04:56 -07:00
Steve Howell
07248ee7bd Use modal.open_overlay() for info overlays. 2017-05-08 22:04:56 -07:00
Steve Howell
4bcb4d6c15 Use modal.open_overlay() in subs.js. 2017-05-08 22:04:56 -07:00
Steve Howell
0965fc5a05 Use modal.open_overlay() in settings/admin. 2017-05-08 22:04:56 -07:00
Steve Howell
b82a802c22 Use modal.open_overlay() in lightbox.js. 2017-05-08 22:04:56 -07:00
Steve Howell
02c743853c Use modal.open_overlay() in invite.js. 2017-05-08 22:04:56 -07:00
Steve Howell
6d1a6934b8 Use modal.open_overlay() in drafts.js. 2017-05-08 22:04:56 -07:00
Steve Howell
09a37ec179 Add modals.open_overlay(). 2017-05-08 22:04:56 -07:00
Steve Howell
2f6edf47bc Fix code format of modals.js.
Our de facto coding standard for JS modules is not indent
within the boilerplate, and we assign functions to `exports`
in single JS statements.
2017-05-08 22:04:56 -07:00
Tim Abbott
9da63bc087 ui: Initialize settings_sections before hashchange.
This is important, since settings_sections must be initialized in
order to load the page with a hash in the settings UI.
2017-05-08 22:02:56 -07:00
Mahim Goyal
6464514ca9 Break compose.js and drafts.js dependency. 2017-05-08 14:43:49 -07:00
Steve Howell
b609911656 Remove unused get_user_profile_by_email() imports. 2017-05-08 11:57:38 -07:00
Steve Howell
3b2a3601c1 tests: Add ZulipTestCase.notification_bot(). 2017-05-08 11:57:38 -07:00
Steve Howell
3a031f6814 test: Use example_user() in more places.
This commit replaces calls to get_user_profile_by_email() with
calls to self.example_user() by introducing a local variable.
2017-05-08 11:57:38 -07:00
Steve Howell
7f9057ba99 tests: Use example_user() in more places. 2017-05-08 11:57:38 -07:00
Steve Howell
6bc8424c71 Use self.example_user() in more places.
This fixes most cases where we were assigning a user to
the var email and then calling get_user_profile_by_email with
that var.

(This was fixed mostly with a script.)
2017-05-08 11:57:38 -07:00
Steve Howell
942db9b6c5 tests: Added ZulipTestCase.example_user() function.
The example_user() function is specifically designed for
AARON, hamlet, cordelia, and friends, and it allows a concise
way of using their built-in user profiles. Eventually, the
widespread use of example_user() should help us with refactorings
such as moving the tests users out of the "zulip.com" realm
and deprecating get_user_profile_by_email.
2017-05-08 11:57:38 -07:00
Mahim Goyal
a44a291cdf Don't open compose when clicking links containing search terms.
Link that is a search term opens compose box, add this exception to
the is_clickable_message_element.

Fixes: #4651.
2017-05-08 11:39:00 -07:00
Tim Abbott
abd09cebb2 git tools: Make error messages more clear. 2017-05-08 10:51:59 -07:00
derAnfaenger
d63fdf5bc6 Fix Twitter bot breaking layout with long words/links.
Long words and links now get automatically broken down in the
'twitter-tweet' div; prevents a message box overflow.

Fixes #4659.
2017-05-08 09:56:35 -07:00
Aditya Bansal
3a097a2a6c pep8: Add compliance with rule E261 to semaphore/view.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
f4a7791d95 pep8: Add compliance with rule E261 to test_template_parser.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
9fb6d976ca pep8: Add compliance with rule E261 to test_server.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
2820eb5a54 pep8: Add compliance with rule E261 to wsgi.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
462786e8b0 pep8: Add compliance with rule E261 to local_settings.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
bbccd8ab28 pep8: Add compliance with rule E261 to zilencer/models.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
b07273c2d0 pep8: Add compliance with rule E261 to commands/profile_request.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
bf24e0c9db pep8: Add compliance with rule E261 to stripe/view.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
3791638985 pep8: Add compliance with rule E261 to semaphore/tests.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
21dd1384b4 pep8: Add compliance with rule E261 to pivotal/view.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
43c978e0f4 pep8: Add compliance with rule E261 to pagerduty/view.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
54989605e0 pep8: Add compliance with rule E261 to github/tests.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
f3c1557529 pep8: Add compliance with rule E261 to beanstalk/view.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
27a1b23392 pep8: Add compliance with rule E261 to ioloop_logging.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
5c82319101 pep8: Add compliance with rule E261 to handlers.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
72d5760d7c pep8: Add compliance with rule E261 to descriptors.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
b48f07ebc0 pep8: Add compliance with rule E261 to test_users.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
feb332920c pep8: Add compliance with rule E261 to test_typing.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
191fead5a3 pep8: Add compliance with rule E261 to test_type_debug.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
fcb1e4d4f1 pep8: Add compliance with rule E261 to test_report.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
2b1c6f7749 pep8: Add compliance with rule E261 to test_queue_worker.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
fd4ac33073 pep8: Add compliance with rule E261 to test_push_notifications.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
0478a9d7f3 pep8: Add compliance with rule E261 to test_export.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
7f5f4a511a pep8: Add compliance with rule E261 to test_decorators.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
ce2790aae2 pep8: Add compliance with rule E261 to test_bots.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
689eb537ae pep8: Add compliance with rule E261 to storage.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
ce4c4f4e0f pep8: Add compliance with rule E261 to migrations/0001_initial.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
8a6617e304 pep8: Add compliance with rule E261 to set_default_streams.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
7271fc8a7b pep8: Add compliance with rule E261 to import.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
d8db632d21 pep8: Add compliance with rule E261 to enqueue_file.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
6a53c53588 pep8: Add compliance with rule E261 to email_mirror.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
f1b2f10574 pep8: Add compliance with rule E261 to dump_messages.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
0999a74ef7 pep8: Add compliance with rule E261 to unminify.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
724c6d384f pep8: Add compliance with rule E261 to type_debug.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
76d28a7cc7 pep8: Add compliance with rule E261 to timeout.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
6ad22f4092 pep8: Add compliance with rule E261 to streams.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
babdb8dd64 pep8: Add compliance with rule E261 to statistics.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
df2b49af66 pep8: Add compliance with rule E261 to sessions.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
94b7e4de9e pep8: Add compliance with rule E261 to rest.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
19adf85d00 pep8: Add compliance with rule E261 to request.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
f7f09df773 pep8: Add compliance with rule E261 to rate_limiter.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
e5bf7e81e6 pep8: Add compliance with rule E261 zerver/lib/queue.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
69cf11d786 pep8: Add compliance with rule E261 to push_notifications.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
d561c758cd pep8: Add compliance with rule E261 to parallel.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
cbaace87cd pep8: Add compliance with rule E261 to email_mirror.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
3687dcdb3f pep8: Add compliance with rule E261 digest.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
0fc16273b9 pep8: Add compliance with rule E261 to ccache.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
101d334b80 pep8: Add compliance with rule E261 to camo.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
e7e7c1a3cd pep8: Add compliance with rule E261 to cache_helpers.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
821be4519c pep8: Add compliance with rule E261 to cache.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
1e61e734c8 pep8: Add compliance with rule E261 to bulk_create.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
c23901c3a8 pep8: Add compliance with rule E261 to fenced_code.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
88811e0d34 pep8: Add compliance with rule E261 to test_user_agent_parsing.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
83db0a98ae pep8: Add compliance with rule E261 to lister.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
46b3c14876 pep8: Add compliance with rule E261 to html_grep.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
47e7437932 pep8: Add compliance with rule E261 to html_branches.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
ffb8440eef pep8: Add compliance with rule E261 to graph.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
c0e1b49b68 pep8: Add compliance with rule E261 to find_add_class.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
fef732d85b pep8: Add compliance with rule E261 to css_parser.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
69f9353ecf pep8: Add compliance with rule E261 to check_help_documentation.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
b3ad6a6d77 pep8: Add compliance with rule E261 to hash_reqs.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
b677689fea pep8: Add compliance with rule E261 to pg_backup_and_purge.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
e83b703780 pep8: Add compliance with rule E261 to docs/conf.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
acfb7c902a pep8: Add compliance with rule E261 to bots/define/define.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
c7a0f26846 pep8: Add compliance with rule E261 to confirmation/settings.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
7940fd9f9a pep8: Add compliance with rule E261 to zephyr_mirror_backend.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
ed21d33663 pep8: Add compliance with rule E261 to summarize_stream.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
df7a569a0c pep8: Add compliance with rule E261 to jabber_mirror_backend.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
199a14c568 pep8: Add compliance with rule E261 to irc-mirror.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
b642696e5d pep8: Add compliance with rule E261 to api/zulip/__init__.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
4ebcbfadd7 pep8: Add compliance with rule E261 to api/setup.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
1efb2cbc7f pep8: Add compliance with rule E261 to zulip_openshift_config.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
3f0b22ce31 pep8: Add compliance with rule E261 to test_counts.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
2ca1f60ac5 pep8: Add compliance with rule E261 to analytics/models.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
13d9b98c39 pep8: Add compliance with rule E261 to analyze_mit.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
9e11185fe2 pep8: Add compliance with rule E261 to active_user_stats.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
27b87943af pep8: Add compliance with rule E261 to counts.py. 2017-05-07 23:21:50 -07:00
Aditya Bansal
6bc653959f Remove empty comment statement from taiga/view.py. 2017-05-07 23:21:50 -07:00
hackerkid
6329b472b0 docs: Update the path of Supervisor config file.
zulip.conf was changed to template file but the update was missed out in the doc.
See ae09d55e46
2017-05-07 23:20:38 -07:00
Umair Khan
b8afd249e4 testing: Make test_hit_ratelimits deterministic.
On slower systems or virtual environments, when you are running
tests in parallel mode, sometimes the time taken to send messages
in this test exceeds 1 second which resets the limit.
2017-05-06 17:28:16 +05:00
Rishi Gupta
962b56efbd settings: Change example NOREPLY_EMAIL_ADDRESS to have a display name.
We used to use constructions like
from_email = "Zulip <%s>" % (settings.NOREPLY_EMAIL_ADDRESS,)
but no longer do. All references to settings.NOREPLY_EMAIL_ADDRESS in the
codebase now do not append a display name.
2017-05-05 14:38:25 -07:00
Rishi Gupta
8321bd3f92 notifications: Refactor missed message queue to use send_email.
This commit also changes the sender from "Zulip <NOREPLY_EMAIL_ADDRESS>" to
NOREPLY_EMAIL_ADDRESS when it is not set explicitly.
2017-05-05 14:38:25 -07:00
Rishi Gupta
fda65b3b37 missed messages: Change subject to always use the plural for Zulips.
Works better for threading in email clients.
2017-05-05 14:38:25 -07:00
Rishi Gupta
60e0bb3a04 send_email: Add reply_to argument to send_email.
django.core.mail.send_mail doesn't support reply_to, so we have to switch to
EmailMultiAlternatives.
2017-05-05 14:38:25 -07:00
Rishi Gupta
face3077df email: Rename template_payload to context. 2017-05-05 14:38:25 -07:00
Rishi Gupta
6a8ed81439 send_email: Remove tags argument from send_future_email.
The tags argument was only being used by the Mandrill pathway, which is no
longer around.
2017-05-05 14:38:25 -07:00
Rishi Gupta
6b9f25a58a Remove duplicated code between send_future_email and send_email pathway.
Note that this change restricts the context for any template that uses
send_future_email to be jsonable.
2017-05-05 14:38:25 -07:00
Rishi Gupta
72ee5e5159 email: Make context for invitation_reminder template jsonable.
We are about to change send_future_email in a way that will require all
callers to use jsonable context.
2017-05-05 14:38:25 -07:00
Rishi Gupta
68c172192b email.py: Change recipients argument of send_future_email to to_email. 2017-05-05 14:38:25 -07:00
Rishi Gupta
0d4c1b0467 notifications: Move send_future_email to zerver/lib/send_email.py. 2017-05-05 14:38:25 -07:00
Rishi Gupta
d70e09b41d notifications: Change sender arg of send_future_email to from_email.
This commit is a step towards the goal of replacing most of the
send_future_email pathway with a call to send_email.

Note that this commit changes the default value of sender from "Zulip
<NOREPLY_EMAIL_ADDRESS>" to "NOREPLY_EMAIL_ADDRESS". NOREPLY_EMAIL_ADDRESS
will soon be changed to have the Zulip in front.
2017-05-05 14:38:25 -07:00
Rishi Gupta
e46cbaffa2 email: Remove Mandrill pathways and dependency.
Everything it was doing (send_future_email) can now be done using
ScheduledJob.
2017-05-05 14:38:23 -07:00
Rishi Gupta
7741e099fc notifications.py: Merge send_local_email_template_with_delay into callers.
Note that the correctness of this commit relies on the fact that
send_future_email also sets the sender to settings.NOREPLY_EMAIL_ADDRESS by
default (in the body of the function).
2017-05-05 14:20:32 -07:00
Rishi Gupta
a413b0dbad notifications: Change send_future_email to take a template_prefix.
Also reorders the arguments a bit to better match
zerver.lib.send_email.send_email.
2017-05-05 14:20:32 -07:00
Rishi Gupta
cf38fd156b digest.py: Merge send_digest_email into its callers.
Most of the functionality of send_digest_email is being standardized in
zerver.lib.notifications.send_future_email.
2017-05-05 14:20:32 -07:00
Rishi Gupta
925ee8c0f1 Add a send_email function that takes a template_prefix and context.
This commit replaces all uses of django.core.mail.send_mail with send_email,
other than in the password reset flow, since that code looks like it is just
a patch to Django's password reset code.

The send_email function is in a new file, since putting it in
zerver.lib.notifications would create an import loop with confirmation.models.

send_future_email will soon be moved into email.py as well.
2017-05-05 14:20:32 -07:00
Rishi Gupta
55a7aa4f9d test_signup: Add dnslookup patch for mirror_dummy_user registration test.
Fixes regression introduced in 326f9a85. The test indirectly makes a call to
email_is_not_mit_mailing_list, which then calls
DNS.dnslookup("%s.pobox.ns.athena.mit.edu" % username, DNS.Type.TXT).
2017-05-05 14:20:32 -07:00
Tim Abbott
d3c05eaf42 templates: Fix alignment issue deactivated users table. 2017-05-05 14:14:37 -07:00
Brock Whittaker
8c715a79b9 Change admin active users list to render progressively. 2017-05-05 14:14:37 -07:00
Brock Whittaker
1a8a8b6d0c Change admin bots list to render progressively. 2017-05-05 14:14:37 -07:00
Brock Whittaker
db40d62092 Change admin streams list to render progressively. 2017-05-05 14:14:37 -07:00
Brock Whittaker
0e4f2f732d Change admin default streams list to render progressively. 2017-05-05 14:14:37 -07:00
Brock Whittaker
6c3606cf36 Change admin deactivated users table to render progressively. 2017-05-05 14:14:37 -07:00
Brock Whittaker
7408656218 Improve list_render implementation's edit flow.
The list_render class "list" prop was immutable so when the
data prop would be updated it would not appropriately update
the data inside the primary list for filtering.

This commit also fixes an issue where if a jQuery selection was
passed in, all the nodes rather than just the first get copied over.
2017-05-05 14:14:12 -07:00
Brock Whittaker
c8902d5d71 settings: Make settings overlay more responsive.
This doesn't completely fix settings responsiveness, but it's a big
step along the way.  Outstanding issues include:

1. When switching tabs from settings to organization, it will launch
the first item which is more annoying in this view since it brings you
into that tab. Haven’t decided on an elegant solution to this yet.

2. Sidebar scrolling doesn’t work. I have to restructure how the top
section and bottom sections of content are displayed to fix this.
Likely by enforcing min-height of 100% - bottom height on the top piece.

3. Most of it is actually reasonably responsive but some isn’t, and
should be fixed on a case-by-case.
2017-05-05 13:42:09 -07:00
Tim Abbott
15c6d683a9 docs: Add notes on future direction to the bots guide. 2017-05-05 13:28:40 -07:00
Tim Abbott
21f766c6dd docs: Further clarify that the bots guide doesn't need your own server. 2017-05-05 13:28:40 -07:00
derAnfaenger
e0ec664994 documentation: Clarify deployment requirements.
This commit removes the false statement that deploying
a bot requires an own Zulip development server and
updates the instructions respectively.
2017-05-05 13:28:40 -07:00
Tim Abbott
f4a1cea488 auth: Refactor conditionals in login_or_register_remote_user. 2017-05-05 10:19:02 -07:00
Tommy Ip
19adf2e327 requirements: Upgrade gitlint to 0.8.2.
As of Gitlint v0.8.2, the --extra-path option now accepts both
directories and standalone python modules.
2017-05-05 09:59:39 -07:00
Brock Whittaker
2ae23054ee informational-overlays: Focus overlay body on shortcut "?".
This focuses the body content of the informational overlay after
going to it from "?" so that you can use up and down arrows to then
scroll the content easily.

Fixes: #4480.
2017-05-05 09:53:58 -07:00
jersou
1a89928999 docker: Fix setting owner of /srv/zulip inside container. 2017-05-05 09:37:38 -07:00
Umair Khan
aee7475319 cache: Add KEY_PREFIX to recipient cache.
This should bounce the recipient cache after every test.
2017-05-05 18:24:08 +05:00
Umair Khan
c62150c097 testing: Bounce redis key prefix per test.
This commit adds a prefix to the redis keys; this allows us
to easily bounce the redis cache before every test.

Fixes: #1212
2017-05-05 18:24:08 +05:00
Umair Khan
4d543217ba cache: Take hash of KEY_PREFIX to limit key size.
Key size of Memcached records should be less than 256.
2017-05-05 18:23:40 +05:00
Cory Lynch
3d0cf35f49 message_edit.js: Fix bug with ctrl+enter hotkey not working.
This was a regression introduced in ba7b7a9. The ID of the
edit boxes were changed in that commit, but this event
listener was not updated to reflect that.
2017-05-04 19:46:10 -07:00
Josh Mandel
92a25f2b91 Update migration instructions to use previous rabbitmq secret. 2017-05-04 19:44:44 -07:00
Rohitt Vashishtha
a2c1e10986 bugdown: Add domain-name to relative image-url in open graph data.
fixes #4608.
2017-05-04 16:54:10 -07:00
Brock Whittaker
1bb260325c settings: Improve general table styling.
This generally makes the tables that have thead attributes look
uniform with the tables that use the first tbody column as a thead.
2017-05-04 16:43:34 -07:00
Tim Abbott
106d83c75a password reset: Fix buggy template quoting. 2017-05-04 16:41:31 -07:00
hackerkid
af612a7e1d Extend test_user_default_language to include timezone test.
This renames the function to test_user_default_language_and_timezone.
2017-05-04 16:37:00 -07:00
hackerkid
83eb161249 Set user timezone automatically during signup. 2017-05-04 16:36:51 -07:00
hackerkid
34dae708d6 Add timezone argument to do_create_user function. 2017-05-04 16:32:05 -07:00
Tim Abbott
e219dda071 reload: Fix tracebacks on browsers without local storage.
This fixes an issue where browsers without local storage (aka the
Zulip ancient QT-based desktop app) would throw an exception trying to
reload in modern Zulip.
2017-05-04 16:21:58 -07:00
Tim Abbott
a493694e10 reload: Clean up handling of invalid reload tokens.
Previously, we'd log an exception whenever an invalid hashchange
reload token appeared, which is probably a bit excessive given that
this can happen without anything being wrong.

We instead just log something for debugging in the blueslip log and
make sure the #reload hash is cleared.
2017-05-04 16:16:35 -07:00
Tim Abbott
f207450cdb presence: Avoid throwing exceptions for "missing users" when offline.
This should eliminate the most common javascript traceback one gets
running Zulip in production.
2017-05-04 16:11:05 -07:00
Tim Abbott
a28f5db050 presence: Check for unsuspend status on receiving responses.
This is the first part of handling an annoying race that would cause
us to try drawing the right sidebar using (in part) users that we
haven't learned about yet (because we were offline/suspended when they
were created, and we haven't quite realized our event queue is gone yet).
2017-05-04 16:11:05 -07:00
Tim Abbott
ecb8d3c7fa password reset: Fix weird translation tags.
There was way too much markup in these translation tags, for no good
reason.
2017-05-04 16:09:12 -07:00
Tim Abbott
b0bd501c0d portico: Remove now-unused hello-footer code. 2017-05-04 16:09:12 -07:00
Brock Whittaker
d21e1ccc1c Unify styling on password reset flow pages. 2017-05-04 16:09:12 -07:00
Brock Whittaker
55b1d480ec Fix avatar sizing issue.
The avatars were previously their natural width, however the avatars
should always be 100% width since the height and width of the images
are known to always be equal.
2017-05-04 16:09:12 -07:00
Brock Whittaker
736701f900 Add account_send_confirm styling. 2017-05-04 16:09:12 -07:00
Brock Whittaker
48ac49385e Fix lack of uniformity with box content layout.
The various portico pages had various styling differences that made
them less consistent when responsive.
2017-05-04 16:09:12 -07:00
Brock Whittaker
89242da269 Remove .footer_padder in favor of proper screen tolerances.
This removes the .footer_padder element in favor of just having correct
min/max heights and margins on the footers.
2017-05-04 16:09:12 -07:00
Brock Whittaker
58d00af6c3 portico-pages: Fix flex height issues with content.
This fixes the existing issue where the titles of content is chopped
off when the screen height is too small.
2017-05-04 16:09:12 -07:00
Umair Khan
6b1c53059b testing: Run in parallel mode by default.
This commit changes the backend testing framework to run
in parallel mode which is same as --processes=4. If --coverage
is supplied, we enforce serial mode, --processes=1, because
coverage is not compatible with parallel mode at the moment.
2017-05-04 16:06:34 -07:00
derAnfaenger
37a8a43cc4 Change cursor to pointer when hovering over streams.
Before this commit, hovering over the blank area of a stream
would not reflect its "clickability". This behavior is
inconsistent with other clickable lists, such as the user sidebar.
This commit changes the cursor to a pointer when hovering over a
stream and removes annoying pointer-default-pointer changes when
hovering with the mouse over multiple users in the user sidebar.
2017-05-04 15:55:51 -07:00
Tim Abbott
33ecfd7da4 auth: Remove require_GET for api_get_auth_backends.
Unfortunately, the Android app incorrectly uses POST with this
endpoint, so the recent change to add this needs to be reverted.
2017-05-04 14:39:02 -07:00
Rishi Gupta
92dd76822f email: Move and rename password reset templates. 2017-05-03 23:26:14 -07:00
Rishi Gupta
c10d3114eb email: Move and rename followup_day* templates. 2017-05-03 23:26:14 -07:00
Rishi Gupta
21a6377204 email: Move and rename find_team_email templates. 2017-05-03 23:26:14 -07:00
Rishi Gupta
ebfae36494 email: Move and rename digest_email templates. 2017-05-03 23:26:14 -07:00
Rishi Gupta
a1f0c1d6ac email: Move and rename new_login_alert templates. 2017-05-03 23:26:14 -07:00
Rishi Gupta
26ac344b19 email: Move and rename invitation_reminder_email templates. 2017-05-03 23:26:14 -07:00
Rishi Gupta
21a2c7b9d9 email: Remove translation tags from email templates.
The only thing being translated in any email was the title of the Zulip
header image in the html file, probably because not doing so breaks a linter
rule.

he name "Zulip" doesn't make sense to translate anyway.
2017-05-03 23:25:33 -07:00
Rishi Gupta
975d5bd8c0 email: Move and rename notify_change_in_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
4e779c3e6f email: Move and rename mituser_invite_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
713303deff email: Move and rename invite_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
ed0c310aa3 email: Move and rename preregistrationuser_confirmation_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
aa21012783 email: Move and rename mituser_confirmation_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
235abe0b72 email: Move and rename emailchangestatus_confirmation_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
0a32d9efa3 email: Fix filenames of notify_change_in_email templates. 2017-05-03 20:54:40 -07:00
Rishi Gupta
cafc60dd1d email: Move and rename missed_message_email templates.
All email templates are being moved to templates/zerver/emails.
2017-05-03 20:54:39 -07:00
Rishi Gupta
30ba989c95 confirmation: Use render_to_string in send_confirmation.
No change in behavior; render_to_string(template, context) is a shortcut for
get_template(template).render(context). render_to_string is the function we
use to render email templates in the rest of the codebase.
2017-05-03 20:54:39 -07:00
Rishi Gupta
04fb86fff7 confirmation: Remove newline replacement from email subjects.
I think it's fine to trust that we won't mess this up. I assume this is here
because it was copied from similar code in Django (e.g. see our code from
the password_reset flow), rather than because it was a problem in our
subject templates.
2017-05-03 20:54:39 -07:00
Rishi Gupta
326f9a8506 email: Fix zephyr mirror registration email not working with subdomains.
If a user is trying to register for a mit zephyr mirroring realm, we send
them a specific registration email with a link to a few more instructions.

There is only one server that we know about that has such a realm, and that
server uses subdomains. This commit changes the logic to work in the
subdomains case, rather than in the non-subdomains case (though see next
para).

Note that the current check is deceptive, and is not actually correct in the
non-subdomains case. The prereg user has a realm only in the atypical case
of someone registering via the special URL for completely-open realms.

To do this correctly in the non-subdomains case, we would need to copy a
bunch of the logic from the beginning of accounts_register to figure out
which realm the user is signing up for, so that we can check if that realm
is a zephyr mirroring realm. Given how complicated the registration code is
already, I think it is probably not worth it at the moment. This commit also
removes the partial (deceptive) check, since I think it does more harm than
good.
2017-05-03 20:52:24 -07:00
Rishi Gupta
6fd3426e92 confirmation: Replace *_template_path arguments with template_prefix.
Relies on the fact that all the email template names now follow the same
pattern.

Note that there was some template_prefix-like computation being done in
send_confirmation (conditioned on obj.realm.is_zephyr_mirror_realm); that
computation is now being done in the callers.
2017-05-03 20:44:57 -07:00
Rishi Gupta
965c9160ad confirmation: Remove references to confirmation_email.* templates.
These look like they were intended to be generic, fallback templates for the
confirmation flow, but were never written.
2017-05-03 19:34:58 -07:00
Rishi Gupta
4027adb6cc email: Fix naming of mituser_invite_email files. 2017-05-03 19:34:58 -07:00
Rishi Gupta
e89c5e4129 email: Fix naming of mituser_confirmation_email files.
I suspect this was actually just broken, and sending a confirmation email to
someone in a zephyr realm wouldn't have worked.
2017-05-03 19:34:58 -07:00
Rishi Gupta
4f20fdc572 user_settings: Update change-email confirmation message. 2017-05-03 19:34:58 -07:00
Tim Abbott
c7ba9a2ae5 templates: Remove old Zulip, Inc. privacy policy.
This isn't useful for anything anymore, especially now since we have a
sysadmin-configurable PRIVACY_POLICY settings.
2017-05-03 17:59:53 -07:00
Tim Abbott
51260b7536 auth: Add new route to get server settings.
Specifically, this makes easily available to the desktop and mobile
apps data on the server's configuration, including important details
like the realm icon, name, and description.

It deprecates /api/v1/get_auth_backends.
2017-05-03 16:40:14 -07:00
Tim Abbott
5d5a314051 auth: Refactor api_get_auth_backends. 2017-05-03 16:40:07 -07:00
Tim Abbott
dad183093a context_processors: Clean up logic for fetching realm. 2017-05-03 16:39:31 -07:00
Brock Whittaker
ed4866b9f9 message-feed: Improve scroll perf by removing scaling on emojis.
This removes scaling from the emojis by changing the background size to
a lower value and then allowing for the widths and heights of the
emojis to be proportionally smaller.

The transform: scale property would cause many more repaints in Chrome
and other browsers than should have been necessary which would render
messages above and below the feed light grey boxes that would
momentarily flash as blank before filling with content.

Modified by tabbott to use a percentage in the background-size.

Fixes #4660.
2017-05-03 14:49:47 -07:00
Tim Abbott
110f161288 emoji: Remove code for generating old sprite sheets. 2017-05-03 13:34:30 -07:00
Tim Abbott
b20a24875a emoji: Switch to using iamcal sprite sheets for reactions and pickers.
Without changing how we render emoji in messages or changing the data
set used for emoji names, this switches us to the superior
percentage-based system for choosing which emoji from the spritesheet
to select and the iamcal sprite sheets.

It requires some small changes to CSS to ensure emoji are centered
properly in the new design.

Based on Harshit Gupta's work on "Interrelated emoji infrastructure changes".
2017-05-03 13:30:42 -07:00
Tim Abbott
ddd3bbd32c echo: Separate realm emoji formatting from normal emoji. 2017-05-03 13:28:50 -07:00
Tim Abbott
b9cb6199cf emoji: Use lower-case hex letters in iamcal data. 2017-05-03 13:01:53 -07:00
Cory Lynch
5d6724345a Fix scrollbar stylining for reactions picker.
Scrollbar previously collapsed when searching for
emoji and became misaligned. Fixed in CSS.
2017-05-02 14:23:26 -07:00
Tim Abbott
179e8c1ba8 do_send_messages: Ensure we fetch bot fields from database.
This increase in the list of needed fields carries a small performance
cost, but it should be very small, and this change is needed to
support outgoing webhooks without additional database queries.
2017-05-02 10:41:47 -07:00
vaibhav
8881b5eb9f Outgoing Webhook System: Check for @-mentioned outgoing webhook bots.
Also puts them into a processing queue, though the queue processor
does nothing.

Rewritten by tabbott to avoid unnecessary database queries in
do_send_messages.
2017-05-02 09:22:04 -07:00
rahuldeve
023730447e Outgoing Webhook System: Add ndg-httpsclient requirement. 2017-05-02 08:24:28 -07:00
rahuldeve
d1a36b5279 Outgoing Webhook System: Add zerver/outgoing_webhooks. 2017-05-02 08:20:31 -07:00
rahuldeve
413c5f93bb Outgoing Webhook System: Add Service model. 2017-05-02 08:20:31 -07:00
Eeshan Garg
c388baa431 docs: Document zerver.models.Client's usage for analytics and webhooks. 2017-05-01 23:50:51 -07:00
Eeshan Garg
e87e246fcb zerver/decorator: Set request.client in api_key_only_webhook_view.
Previously, api_key_only_webhook_view passed 3 positional arguments
(request, user_profile, and client) into a function. However, most
of our other auth decorators only pass 2 positional arguments. For
the sake of consistency, we now make api_key_only_webhook_view set
request.client and pass only request and user_profile as positional
arguments.
2017-05-01 23:44:07 -07:00
sinwar
2e0c03ae2d requirements: Update psycopg2 to latest version.
Fixes #4580.
2017-05-01 23:43:28 -07:00
sinwar
5c3cb79747 streams: Ban null character from stream name.
This is a better solution to the problem of how _pg_re_escape should
handle the null character.  There's really no good reason to have a
null character in a stream name.
2017-05-01 23:43:01 -07:00
Tim Abbott
07db233ffd register: Remove long-unused company-email HTML/CSS. 2017-05-01 17:18:03 -07:00
Rohitt Vashishtha
47eb19331d ux: Display error on login/registration if no auth backends are enabled.
Also makes a small tweak to CSS to ensure the styling is consistent on
the two pages.

Fixes #4525.
2017-05-01 17:17:37 -07:00
Brock Whittaker
2fafc6bec5 Change streams subscriber lists to render progressively. 2017-05-01 16:56:54 -07:00
Brock Whittaker
4e980ad545 Change <thead> styling in settings containers.
Tables were previously improperly using the <tbody> to show the headers
so it was not obvious that the styling for <thead> did not represent
the styling of the rest of the tables anymore, so this normalizes
the styling to be consistent with how it looked when the first row
was in the <tbody>.
2017-05-01 16:56:54 -07:00
Brock Whittaker
0ffdfa3699 Change from toLowerCase => toLocaleLowerCase.
This now respects the locale of the string set and will lowercase it
respective of the character set rather than standard latin/English.
2017-05-01 16:56:54 -07:00
Steve Howell
23df948457 left sidebar: Scroll to newly pinned streams.
If we pin a stream, we now scroll up as needed to make sure the
stream is still in view after pinning it.  (Note that we don't do
this in the un-pinning case, since users un-pinning stuff may be
doing cleanup on pinned streams they no longer care about.)

Fixes #1714.
2017-05-01 16:39:37 -07:00
Steve Howell
07633b3872 left sidebar: Scroll to newly activated streams.
When we activate a stream (or one of its topics), we now scroll
the sidebar so that the stream comes into view.  We scroll it
just enough to get it to the top or the bottom, depending on
where it had been offscreen before.
2017-05-01 16:39:37 -07:00
Steve Howell
711a50f1e8 Add internal_prep_private_message().
The new function takes a full UserProfile object for the sender,
which allows us to avoid O(N) calls when creating the stream to
find the user profile of the notification bot.  (The calls were
already cached, so this won't necessarily be a huge performance
win.)

We also don't have to worry about sending a blank subject any more.
2017-05-01 16:23:38 -07:00
Steve Howell
0f4de8e37d Add internal_prep_stream_message().
The new, more direct interface for prepping internal stream
messages circumvents the bug-prone extract_recipients() method,
which has the pitfall that it will try to parse a stream name
as JSON.  It also takes a UserProfile object for the sender, so
it's a bit more type-safe.
2017-05-01 16:23:38 -07:00
Steve Howell
e3edc4d829 Send welcome messages for new streams. 2017-05-01 16:23:38 -07:00
Brock Whittaker
f599b517d3 Switch checkbox styling to new style in #invite.
The checkboxes in invite are now converted in this commit to the new
style.
2017-05-01 16:01:36 -07:00
Brock Whittaker
3ff55034fe admin: Restyle administration checkboxes to match new style.
This restyles the administration checkboxes to look similar to those
that are currently present in the settings section.
2017-05-01 16:01:36 -07:00
Tim Abbott
84008b9c37 context_processors: Rename confusingly named add_settings context.
Also document this.
2017-05-01 15:47:58 -07:00
Tim Abbott
f4262e0169 message_edit: Fix exception closing "view source".
This fixes a regression introduced in
81a575e4d5.
2017-05-01 15:08:01 -07:00
Tim Abbott
03b7be17a6 settings: Fix unnecessary/ugly exclamations in error messages.
The previous code would produce errors of the form "Failed!: ...".
2017-05-01 14:50:20 -07:00
K.Kanakhin
f13d6a18eb realm-emoji: Add realm emoji uploading instead url providing.
- Add file_name field to `RealmEmoji` model and migration.
- Add emoji upload supporting to Upload backends.
- Add uploaded file processing to emoji views.
- Use emoji source url as based for display url.
- Change emoji form for image uploading.
- Fix back-end tests.
- Fix front-end tests.
- Add tests for emoji uploading.

Fixes #1134
2017-05-01 14:50:20 -07:00
Tim Abbott
0785c377a4 zephyr: Fix link to webathena login from error bar.
This was apparently broken when we moved the webathena login errors
out of the right sidebar.
2017-04-30 21:31:25 -07:00
Tim Abbott
445cf8c680 reactions: Add a test for the Zulip emoji.
This fixes a coverage problem introduced by recent emoji refactoring.

Also, it'll help prevent us from breaking this feature in the future.
2017-04-30 20:16:51 -07:00
Tim Abbott
85805cf380 bugdown: Simplify logic for constructing unicode_emoji_list. 2017-04-30 16:40:58 -07:00
Tim Abbott
8b3be3cd3a bugdown: Pass a codepoint, not a URL, to make_emoji. 2017-04-30 16:40:58 -07:00
Tim Abbott
a7efe222ee tests: Use slightly_smiling_face instead of simple_smile.
The latter name is likely to be removed in the near future.
2017-04-30 16:40:58 -07:00
Tim Abbott
565370a365 bugdown: Create make_realm_emoji function.
Currently, this is a duplicate of the existing make_emoji, but the
plan is to change that in some upcoming refactoring.
2017-04-30 16:40:58 -07:00
Tim Abbott
18bd566958 bugdown: Extract unicode_emoji_to_codepoint. 2017-04-30 16:40:58 -07:00
Tim Abbott
e0a8f383b3 bugdown: Remove unnecessary first argument to make_emoji. 2017-04-30 16:40:58 -07:00
Tim Abbott
cfeff245c1 emoji: Manage Zulip emoji as a custom/extra realm emoji.
This is prerequisite for converting our emoji system to work off of
iamcal sprite sheets.

Also, fixes #4308.
2017-04-30 16:40:31 -07:00
Tim Abbott
5321e2e2c1 hotkey: Reorder compose and emoji picker escape handlers.
This fixes an issue where escape could close the compose box, not the
compose emoji picker.
2017-04-30 15:15:33 -07:00
Jack Zhang
df817f12f4 emoji: Rename reaction-popover to emoji-popover.
The name emoji-popover should now be more appropiate, as there's no more
need to distinguish between reacting to messages and composing messages.
2017-04-30 15:15:33 -07:00
Jack Zhang
a9505654da emoji: Replace the old compose emoji picker with the reactions picker.
This removes the old compose emoji picker in its entirety, changing
the few callbacks needed to launch the reactions-style emoji picker
instead and hook it up properly.

Callbacks for reactions and composing messages are distinguished by
selecting for, respectively, the .reaction and .composition classes.

Fixes #4122.
2017-04-30 15:14:42 -07:00
Jack Zhang
58a92a0eff emoji: Extend reaction_popover_content template for compose. 2017-04-30 15:09:43 -07:00
Tim Abbott
87d06268ca toggle_reactions_popover: Support being passed no message ID.
This is intended to facilitate calling this function for the compose
picker, where there is no message yet.
2017-04-30 15:08:51 -07:00
Jack Zhang
3c257a19c0 emoji-picker: Extract generate_emoji_picker_content.
This is a pure refactor, with no functional changes.
2017-04-30 15:02:12 -07:00
Tim Abbott
66f927762b emoji_picker: Extract compute_placement function.
Thanks to Jack Zhang for identifying this useful refactoring.
2017-04-30 14:41:54 -07:00
Jack Zhang
f8b3ce7d15 emoji: Move all emoji picker logic/events into emoji_picker module.
Added emoji_picker.js to static asset pipeline.
2017-04-30 14:13:36 -07:00
Alexander Trost
889547ff5e configure-rabbitmq: Add support for RABBITMQ_NODE flag.
This can potentially be used by things like a Docker configuration
that runs RabbitMQ on another server.
2017-04-29 15:03:05 -07:00
Eeshan Garg
8ef18463d6 github_webhook: Use author's full name if username is not available.
In cases where the webhook payload doesn't have the username for the
author of a particular commit (this can happen if the author doesn't
have a GitHub account or the author's email is not associated with
their GitHub account), we now use the author's full name to format
messages.
2017-04-29 14:57:57 -07:00
Aditya Bansal
cab87fef2a Refactor: Extract default-language-modal to be a partial.
We are doing this refactor for the sake of keeping our template
consistent with the indentation policy and maintaining its
readability at the same time.
2017-04-29 08:35:25 -07:00
fionabunny
78f2df5649 home.py: move initial_pointer as pointer to register_ret.
This is the last of the fields in page_params that could come from
register_ret but wasn't doing so.
2017-04-28 23:39:14 -07:00
fionabunny
d3e7e6542a home.py: move user_profile full_name to register_ret.
Move the user_profile data section down into fetch_initial_state_data
so it entirely pulls from register_ret for #3853.
2017-04-28 23:31:28 -07:00
fionabunny
d5421f25e1 home.py: move user_profile email to register_ret.
Move the user_profile data section down into fetch_initial_state_data so
it entirely pulls from register_ret for #3853
2017-04-28 23:27:34 -07:00
fionabunny
9daf9faa5c home.py: move enter_sends to register_ret.
Move the user_profile data section down into fetch_initial_state_data so
it entirely pulls from register_ret for #3853
2017-04-28 23:26:28 -07:00
fionabunny
6f770c2465 home.py: move user_id to register_ret.
Move the user_profile data section down into fetch_initial_state_data so
it entirely pulls from register_ret for #3853
2017-04-28 23:26:28 -07:00
fionabunny
6159b8e21a home.py: move is_admin to register_ret.
Move the user_profile data section down into fetch_initial_state_data so
it entirely pulls from register_ret for #3853
2017-04-28 23:26:27 -07:00
fionabunny
d92da7d193 home.py: move can_create_streams to register_ret.
Move the user_profile data section down into fetch_initial_state_data
so it entirely pulls from register_ret for #3853.

This field requires some changes to the events race handling.
2017-04-28 23:23:21 -07:00
fionabunny
379a8afaae home.py: move autoscroll_forever to register_ret.
Move the user_profile data section down into fetch_initial_state_data so
it entirely pulls from register_ret for #3853
2017-04-28 23:16:32 -07:00
fionabunny
22be291d96 home.py: move default_desktop_notifications to register_ret.
Move the user_profile data section down into fetch_initial_state_data so
it entirely pulls from register_ret for #3853
2017-04-28 23:16:32 -07:00
Tim Abbott
df8f4a837c home: Get page_params.enable_desktop_notifications from register_ret. 2017-04-28 23:15:35 -07:00
Tim Abbott
c4eeb13353 account-settings: Always display the medium-size avatar. 2017-04-28 23:09:32 -07:00
fionabunny
4696819629 Restructure format of avatar events and push into register_ret.
This moves the avatar_ fields in page_params to come from
register_ret.  Unlike many fields, changing this had a bit of
complexity, because the avatar update events didn't actually contain
some of the details required for moving these into register_ret to
work correctly without races.

We fix that as part of this change.

Modified significantly by tabbott.
2017-04-28 23:04:01 -07:00
Tim Abbott
c63466cae3 home: Get pm_content_in_desktop_notifications from register_ret. 2017-04-28 22:06:32 -07:00
Tim Abbott
2a16cc1d24 home: Get enable_stream_desktop_notifications from register_ret. 2017-04-28 22:01:46 -07:00
Tim Abbott
2a8a101fe2 home: Get page_params.enable_stream_sounds from register_ret. 2017-04-28 21:56:58 -07:00
Tim Abbott
30db811167 home: Get page_params.enable_sounds from register_ret. 2017-04-28 21:54:05 -07:00
Tim Abbott
a0ef1210eb home: Get enable_offline_email_notifications from register_ret. 2017-04-28 21:51:41 -07:00
Tim Abbott
1141111b74 home: Get enable_online_push_notifications from register_ret. 2017-04-28 21:51:07 -07:00
Tim Abbott
68cdbdd478 home: Get enable_offline_push_notifications from register_ret. 2017-04-28 21:50:41 -07:00
Tim Abbott
ba384240b0 home: Get enable_digest_emails from register_ret. 2017-04-28 21:50:12 -07:00
fionabunny
83191cfadf home.py: move timezone to register_ret.
Moving the user_profile data section down into fetch_initial_state_data
so it entirely pulls from register_ret in #3853
2017-04-28 21:40:37 -07:00
fionabunny
16a0327c33 home.py: move emojiset to register_ret.
Moving the user_profile data section down into fetch_initial_state_data
so it entirely pulls from register_ret for #3853
2017-04-28 21:40:36 -07:00
fionabunny
2bdb6a00a7 home.py: move emojiset_choices to register_ret.
Moving user_profile data to fetch_initial_state_data from #3853
2017-04-28 21:40:26 -07:00
fionabunny
78bcbc79d6 home.py: move people_list as realm_users to register_ret.
Simplify the page_params generation logic #3853
2017-04-28 21:33:33 -07:00
fionabunny
7db8c61aac home.py: move event_queue_id as queue_id to register_ret.
Simplify the page_params generation logic #3853
2017-04-28 21:33:17 -07:00
Tim Abbott
27f07e6a99 activity: Remove page_params.presences after use.
This is just meant to avoid there being any confusion about whether
this field does anything after this point.
2017-04-28 21:31:19 -07:00
fionabunny
453fc06686 home.py: move initial_presences as presenses to register_ret.
Simplify the page_params generation logic #3853.
2017-04-28 21:30:29 -07:00
fionabunny
84c4d67916 home.py: move bot_list as realm_bots to register_ret.
Simplify the page_params generation logic #3853
2017-04-28 21:24:44 -07:00
fionabunny
a7192f4334 home.py: move neversubbed_info as never_subscribed to register_ret.
Simplify the page_params generation logic #3853
2017-04-28 21:24:44 -07:00
fionabunny
5676eaab50 home.py: move unsubbed_info as unsubscribed to register_ret.
Simplify the page_params generation logic #3853
2017-04-28 21:24:43 -07:00
fionabunny
26d080cf64 home.py: rename subbed_info and move to register_ret. 2017-04-28 21:24:43 -07:00
fionabunny
b7c6d46bf9 home.py: move password_auth_enabled as realm_password_auth_enabled.
Part of #3853.
2017-04-28 21:23:48 -07:00
fionabunny
635a05fe80 home.py: move name_changes_disabled as realm_name_changes_disabled.
This appears to have been partially completed prior.  Part of #3853.
2017-04-28 21:12:23 -07:00
fionabunny
70fe2eab60 home.py: move is_zephyr_mirror_realm as realm_is_zephyr_mirror_realm.
Part of #3853.
2017-04-28 21:12:16 -07:00
fionabunny
935ddf3b17 home.py: move show_digest_email as realm_show_digest_email.
Part of #3853.
2017-04-28 21:12:10 -07:00
fionabunny
64041e0da1 home.py: move mandatory_topics as realm_mandatory_topics to register_ret.
Part of #3853.
2017-04-28 21:12:05 -07:00
fionabunny
79c989916d home.py: move realm_presence_disabled to register_ret.
Part of #3853.
2017-04-28 21:12:00 -07:00
fionabunny
6d2785c853 home.py: move domains as realm_domains to register_ret.
Part of #3853.
2017-04-28 21:11:56 -07:00
Tim Abbott
4a67ba241e realm_domains: Restructure library for getting realm domains.
* Remove duplicate list_of_domains_for_realm of get_realm_domains.
* Move get_realm_domains from actions.py.
2017-04-28 21:11:56 -07:00
fionabunny
504de6abc2 home.py: move realm_uri to register_ret.
Part of #3853.
2017-04-28 21:11:50 -07:00
Steve Howell
6057c444e2 Extract _internal_prep_message().
The function internal_prep_message is kind of awkward to
call, so I'm moving most of its implementation to
_internal_prep_message() for upcoming refactorings.
2017-04-28 20:58:09 -07:00
Cory Lynch
e972453a73 message edit: Remove Topic and Content labels.
Removed the components from the template and
cleaned up the relevant css.

Fixes #4562
2017-04-28 20:57:06 -07:00
Steve Howell
4762673929 Fix how we calculate fields in stream_data.js.
We used to have code scattered in multiple places to
calculate things like admin options, preview urls,
subscriber counts, and rendered descriptions for
streams before we rendered templates in the "Manage
Stream" code.

These are all consolidated into a new function
called stream_data.update_calculated_fields().

This is mostly code cleanup, but it also fixes a bug where
the "View Stream" button would not work for a newly created
stream.
2017-04-28 17:49:33 -07:00
Rafid Aslam
7b2ef7c1a9 compose: Validate subscriptions in browser when !autosubscribe.
This doesn't quite complete the goals of #4650, which has a plan for
how to remove this entirely, but it causes this problematic code to
now be contained to a very rare case.

Refactored significantly by tabbott just due to rebase age.

Fixes #3629.
2017-04-28 17:46:15 -07:00
Tim Abbott
3f1df50c7b compose: Remove unnecessary check_stream_existence wrapper.
This function had become just an empty shell.
2017-04-28 17:41:12 -07:00
Tim Abbott
e0954d8811 compose: Refactor check_stream_for_send error handling.
The extra lines in removed were already part of compose_error.
2017-04-28 17:41:02 -07:00
Cory Lynch
0965c43238 Add typeahead for syntax highlighting languages.
Modified composebox_typeahead.js to recognize the triple backtick
and tilde for code blocks, and added appropriate typeahead functions
in that file and in typeahead_helper.js.

Additionally, a new file pygments_data.js contains a dictionary of
the supported languages, mapping to relative popularity
rankings. These rankings determine the order of sort of the
languages in the typeahead.

This JavaScript file is actually in static/generated/pygments_data.js, as it
is generated by a Python script, tools/build_pymgents_data.py. This is
so that if Pygments adds support for new languages, the JavaScript file
will be updated appropriately. This python script uses a set of popularity
rankings defined in lang.json.

Corresponding unit tests were also added.

Fixes #4111.
2017-04-28 17:22:59 -07:00
Steve Howell
73096e377a minor: Update JS dependency configuration. 2017-04-28 16:17:52 -07:00
Steve Howell
5965dc092a Move check_stream_existence() to compose.js.
The function check_stream_existence() temporarliy got moved
to stream_create.js, and our call from compose.js was still trying
to find it in subs.js.  Now we move the function to compose.js,
since we no longer use it stream_create.js.

This function is pretty dubious, and we may want to only check
for duplicate stream names locally.
2017-04-28 16:17:52 -07:00
Steve Howell
d999827465 Improve how we report errors when we name new streams.
When the user creates a stream, we no longer do a synchronous
check on the back end to find if the stream name already exists.
Instead, we only check our local data, which will prevent many
typical errors, and then we let the back end capture duplicates for
stream names that the client doesn't know about.

We also tone down errors when the stream name is blank--we
only whine about empty streams right before submitting the form.

Also, since our check for duplicate streams is less expensive,
we now capture the "input" event instead of the "focusout" event,
so that if you fix up the name to avoid a collision, you get more
immediate feedback.

When we do detect stream name errors, we conveniently focus the
text field to let the user correct the problem.
2017-04-28 16:17:52 -07:00
Rishi Gupta
92978d6fb2 analytics: Fix --utc argument in update_analytics_counts.py. 2017-04-28 16:15:07 -07:00
Rishi Gupta
73ae2abd4e analytics: Add --verbose option to update_analytics_counts.py. 2017-04-28 16:15:07 -07:00
Rishi Gupta
cf90fed418 stats: Remove users_today from Active Users.
It's technically the number of users yesterday. Also, "number of active
users today" suggests something like daily actives today, whereas this graph
currently shows 2-week actives.
2017-04-28 16:15:07 -07:00
Rishi Gupta
b99e5aeb0b stats: Change title for Number of Users graph.
This stat used to have the total number of users, but was changed in f595f4f
to be the number of 2-week actives.
2017-04-28 16:15:07 -07:00
Rishi Gupta
61bf445da4 analytics: Restrict fill_to_time to hour boundaries in process_count_stat. 2017-04-28 16:15:07 -07:00
Rishi Gupta
dfbeab73b5 analytics: Change update_analytics_counts to only use hour boundaries.
Fixes a recent regression where analytics were not being run on hour
boundaries.

Includes a migration that dumps all the analytics data.
2017-04-28 16:15:07 -07:00
Tim Abbott
8d0f48a71f mypy: Fix duplicate annotation in test_narrow. 2017-04-28 15:47:26 -07:00
Raghav Jajodia
60362a0bec test_narrow: Add test for search operation using email.
Fixes #3074.

(Note the main issue was actually fixed by
2f09866364); this just adds a test.
2017-04-28 15:40:50 -07:00
Tim Abbott
a0e276c54a settings: Fix autocomplete in email change form. 2017-04-28 14:39:18 -07:00
Tim Abbott
a7f85739a9 login: Fix extra '.' in template after wrong_subdomain_error. 2017-04-28 14:34:20 -07:00
Tim Abbott
6c9daf7c3b alerts: Clean up network error messages a bit. 2017-04-28 12:58:30 -07:00
Brock Whittaker
c7cb20d873 alerts: Polish .alert-box .alert styling.
This polishes the styling on the alerts inside of the .alert-box to
have more appropriate colors, margins, and padding.
2017-04-28 12:50:04 -07:00
Tim Abbott
ec90f0c342 Disable gitlint commit message linter for now.
We've found a couple major issues that we need to fix:
* TRAVIS_COMMIT_RANGE being computed incorrectly in some cases (?!)
* The imperative linter could use some work.
2017-04-28 12:26:26 -07:00
Cory Lynch
ba7b7a9a36 Change edit_message_content to have unique IDs for different messages.
Fixes bugs of when multiple messages are being edited simultaneously.
Specifically, typeahead is no longer broken, copying messages to clipboard
is less buggy, and resizing is no longer
broken when multiple messages are being edited.
2017-04-28 12:15:34 -07:00
Cory Lynch
81a575e4d5 Add cleanup for resize listeners on message editing.
I changed the watch_manual_resize function to return the listener
functions it creates, and then these are used to remove the event
listeners before the edit box is hidden.
2017-04-28 12:15:34 -07:00
Cory Lynch
f9d1bff167 Fix textarea resize for editing messages.
Reusing code from the main compose_message component so that resizing now
behaves correctly. This means that when the user tries to resize vertically,
the autoresize code is disabled, and the textbox reverts to manual resizing.
Fixes #4573
2017-04-28 12:15:34 -07:00
Neeraj Wahi
90a154e451 Add mobile auth redirect to custom URI scheme (zulip://).
This makes it possible for the Zulip mobile apps to use the normal web
authentication/Oauth flows, so that they can support GitHub, Google,
and other authentication methods we support on the backend, without
needing to write significant custom mobile-app-side code for each
authentication backend.

This PR only provides support for Google auth; a bit more refactoring
would be needed to support this for the GitHub/Social backends.

Modified by tabbott to use the mobile_auth_otp library to protect the
API key.
2017-04-28 11:47:35 -07:00
Tim Abbott
0566b8dd73 auth: Fix prams typo in Google auth code path. 2017-04-28 11:47:35 -07:00
Tim Abbott
83fe8d4420 auth: Simplify code for Google CSRF state.
This will make it much easier to avoid adding new things that aren't
actually included in the CSRF hash of the other parameters.
2017-04-28 11:47:35 -07:00
Tim Abbott
54b899860d auth: Add GitHub to list of reported backends. 2017-04-28 11:47:35 -07:00
Tim Abbott
45b2b25026 mobile: Add mobile one-time-pad library.
We'll need to implement a version of the simple decoding/decryption
logic used by this library in the mobile code as well, but that should
be simple enough.
2017-04-28 11:47:35 -07:00
Tim Abbott
1b8c3398e7 models: Extract API_KEY_LENGTH constant. 2017-04-28 11:47:35 -07:00
Tim Abbott
ce33368905 GoogleOAuthTest: Include the /accounts/login/google/ step in tests.
This makes our Google auth tests a bit more faithful, in that they now
follow the full Oauth flow, rather than skipping the first step.
2017-04-28 11:47:35 -07:00
Tim Abbott
8b78f22660 GoogleOAuthTest: Refactor parameter encoding. 2017-04-28 11:47:35 -07:00
Eeshan Garg
8ad3a8bc9a integration-guide: Replace references to old-style fixture directories.
The integration guide has now been updated to reflect the recent
decision to store webhook fixtures in
zerver/webhooks/<webhook_name>/fixtures/ as opposed to
zerver/fixtures/<webhook_name>/.
2017-04-28 11:07:03 -07:00
Eeshan Garg
b3ffffd3b7 webhook-walkthrough: Replace references to old-style fixture directories.
The webhook walkthrough has now been updated to reflect the recent
decision to store webhook fixtures in
zerver/webhooks/<webhook_name>/fixtures/ as opposed to
zerver/fixtures/<webhook_name>/.
2017-04-28 11:07:03 -07:00
Eeshan Garg
aa12002be7 webhooks: Move all fixtures to zerver/webhooks/<webhook_name>/fixtures.
All webhook fixtures in zerver/fixtures/<webhook_name> have now
been moved to dedicated webhook-specific directories under
zerver/webhooks/<webhook_name>/fixtures, where <webhook_name> is
the name of the webhook.
2017-04-28 11:07:03 -07:00
Brock Whittaker
dcc2b3a900 left-sidebar: Restructure <a> to cover the <li>.
This restructures the <a> tag to be clickable essentially anywhere
within the <li> tags, unlike before where due to it being “inline”, you
had to hover over the text in particular.
2017-04-28 09:56:15 -07:00
Brock Whittaker
e7ac6710e9 Resize <li> text and align icons.
This resizes the text of the line items to be 5% larger and aligns
the #global_filters icons to be centered vertically.
2017-04-28 09:56:15 -07:00
Steve Howell
0ced7cfc55 Make newly subscribed streams appear active.
When you subscribe to a stream, we now set a newly_subscribed
flag on the object, and we return true during the is_active()
call.

This solves the problem that immediately after you subscribe, you
don't have any messages in the stream, so it would appear active
by our old criteria.

This is still something of a workaround, as once you reload, the
stream will become inactive again, unless other messages come in.

A more permanent solution here would be to have the backend
indicate newly subscribed streams to us (apart from the initial
event), but we may not really need that in practice.
2017-04-28 07:40:25 -07:00
Steve Howell
f9b3ff8f68 Change argument type for stream_data.is_active().
The function now takes a "sub" object instead of a stream
name.
2017-04-28 07:39:52 -07:00
Steve Howell
62d530196b Fix test_sort_streams().
It turns out the check to make sure that "social" filtered to
the bottom could give a false positive, since it was already
alphabetically at the end of the list.

So, I call the stream "cars" now instead, so that it only comes
after "Denmark" if the is_active flag gets respected.

I also check for the divider tags now.
2017-04-28 06:39:17 -07:00
K.Kanakhin
e2cf6102fb test_tornado.py: Add websocket closing to tornado tests.
- Extend tornado tests with closing WebSocket connection
to avoid leakings warnings.
- Mark test_tornado as having 100% coverage.

Fixes #3942.
2017-04-27 12:05:56 -07:00
Umair Khan
d011bd736d api_auth: Change email to identifier.
We can have an email or a server uuid as an argument so identifier
looks like a more appropriate name
2017-04-27 11:30:53 -07:00
Tim Abbott
331207a02b create_realm: Fix heading for creating an organization. 2017-04-27 11:12:09 -07:00
Tim Abbott
3fa6bdf49c login: On single-realm servers, assume the only open realm.
This makes it possible to display the nice new login/registration
banner on single-realm servers, which is the common case.
2017-04-26 18:04:05 -07:00
Brock Whittaker
7afbc9ddd6 Redesign login and registration pages.
This completes a major redesign of the Zulip login and registration
pages, making them look much more slick and modern.

Major features include:
* Display of the realm name, description and icon on the login page
  and registration pages in the subdomains case.
* Much slicker looking buttons and input fields.
* A new overall style for the exterior of these portico pages.
2017-04-26 18:04:05 -07:00
Brock Whittaker
6e512dddcb left-sidebar: Make <li> height and icon size consistent.
This makes the height of the list-items all 24px and changes
the home icon to be a slightly larger 16px instead of 14px which
looked visually smaller than the other icons.
2017-04-26 17:13:03 -07:00
Diego Berrocal
e0a45640d2 Documentation: Improve new feature tutorial.
Resolves a few comments from #4598.
2017-04-26 16:19:51 -07:00
Tim Abbott
2708062181 events: Add support for fetch_event_types option to events_register.
This new feature makes it possible to request a different set of
initial data from the event_types an API client is subscribing to.

Primarily useful for mobile apps, where bandwidth constraints might
mean one wants to subscribe to events for a broader set of data than
is initially fetched, and plan to fetch the current state in future
requests.
2017-04-26 16:02:40 -07:00
Eeshan Garg
ffdd5d3588 webhooks: Don't display "Commits by" when committer is the only author.
For our Git integrations, we now only display the number of commits
pushed when the pusher also happens to be the only author of the
commits being pushed.

Part of #3968.
Follow-up to #4006.
2017-04-26 18:26:09 -02:30
Eeshan Garg
b7ca533315 webhooks: Add a space between author and number of commits for Git messages.
For Git push messages, we now have a single space character between
the name of a commit's author and the number of commits by that
author, plus a period at the end.

Part of #3968.
Follow-up to #4006.
2017-04-26 18:26:09 -02:30
Eeshan Garg
af69faafc9 webhooks: Use author's name to format Git push messages.
We now use the name of the author of a commit as opposed to the
committer to format Git messages with multiple committers.

Part of #3968.
Follow-up to #4006.
2017-04-26 18:26:09 -02:30
K.Kanakhin
18f2a7428f Fix missing aggregated info in real-time sync race for presence.
- Add aggregated info to real-time updated presence status.
- Update `presence events` test case with adding aggregated
  information to presence event.
- Add test case for updating presence status for user which
  send state from multiple clients.

Fixes #4282.
2017-04-26 13:20:22 -07:00
Cory Lynch
088d881159 compose: Improve ordering in streams typeahead.
The new logic has 4 tiers of priority:
* Whether a match is found in the name, start of description, middle
of description, etc.
* Importance to the user / activity -- more specifically, the order
used in the left sidebar. This means pinned streams first, active
streams, then inactive streams.
* Subscriber count: How big is the stream?  Bigger is better.
* Alphabetical ordering is a final tiebreak.

Fixes #4508.
2017-04-26 12:46:14 -07:00
Brock Whittaker
2fce6a4dc3 message-feed: Fix message drag uncaught errors.
There is a mechanism to prevent a user from "clicking" on a message
if they drag over it, to allow people to copy message contents without
triggering the compose box to open.

In the case that a user would start dragging from outside a message
and finish dragging within a message, data on where the cursor started
at is missing.

This is fixed by checking if start data exists and if it doesn't, we
just throw a drag distance of Infinity which will tell the program to
not count the action as a "click" on the message. This now does not
have an uncaught error because it instead validates "start" as existing
before attempting to access its properties.
2017-04-26 12:31:14 -07:00
Tim Abbott
5d7aa4fae7 hashchange: Fix buggy narrowing to wrong message.
Due to a past refactoring, the from_reload argument to do_hashchange
changed from having true/undefined as the possible values to
true/false instead.  The check that sets the from_reload and
first_unread_from_server narrow options was thus incorreclty treating
from_reload of false the same as a from_reload of undefined.

As a result, if the browser had been loaded with a
page_params.initial_narrow_pointer (aka via the background reload code
path), then for the duration of that browser session, every time one
narrowed via a hashchange rather than an explicit click handler (which
apparently includes clicking on a PM thread in the left sidebar), we'd
end up narrowing with a then_select_id of the that initial narrow
pointer, not the correct first unread message.

The fix is simply changing the check for truthiness, not undefined, in
do_hashchange.
2017-04-26 12:07:56 -07:00
Umair Khan
f4a9651346 reload: Garbage collect previously preserved state.
This fixes a minor local storage data leak.

Fixes: #4545.
2017-04-26 09:14:46 -07:00
Umair Khan
58a82e7c55 localstorage: Allow regex based delete. 2017-04-26 09:11:44 -07:00
Umair Khan
ce5980aa45 testing: Don't destroy template DB in parallel mode. 2017-04-26 13:59:42 +05:00
Aditya Bansal
e961d6a834 Clean account-settings.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
6f49579e65 Clean actions_popover_content.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
acef0b1f32 Clean bot_avatar_row.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
ae2585ac8d Clean admin_user_list.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
af880b8bab Clean ui-settings.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
73cd6948de Clean realm-filter-settings-admin.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
d5bb128f56 Clean notification-settings.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
338c2d618a Clean display-settings.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
a2d0976002 Clean deactivation-user-modal.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Aditya Bansal
4219bec14f Clean auth-methods-settings-admin.handlebars to use 4 space indents. 2017-04-26 00:16:22 -07:00
Tim Abbott
c4716aefc7 mypy: Move type: ignore check to the line with the error.
Fixes https://travis-ci.org/zulip/zulip/jobs/225841310

I'm pretty sure the fact that I need to do this is a mypy bug.
2017-04-25 23:44:41 -07:00
Tim Abbott
cb6373210b logging_handlers: Fix tracebacks being emailed in subject lines.
Some exceptions happening in queue processors were being incorrectly
emailed out in the subject line, rather than the body, of the error
report.
2017-04-25 18:55:11 -07:00
Rishi Gupta
f595f4f7f2 analytics: Change Number of Users chart to use realm_active_humans::day.
Previously we showed the total number of users with an active account. This
changes it to show only the number of users that have logged in in the past
two weeks.
2017-04-25 18:35:13 -07:00
Tim Abbott
b43385ec34 Shrink max display width of topics.
This fixes an issue with topic names overlapping in the left sidebar.
While we're doing that, it makes sense to shrink the maximum size of
the topic input box, to discourage sending with topics that will be
cut off.
2017-04-25 17:51:47 -07:00
Brock Whittaker
3d64d190c1 Change right sidebar unread counts to be rounded.
This changes the right sidebar unread count styling to match the left
sidebar styling — in that they all now should have a 4px border radius
on the edges of the unread count blocks.
2017-04-25 17:47:36 -07:00
Brock Whittaker
c506a92d05 left-sidebar: Restyle to have new look.
This restyles the color swatches to either be locks or hashes,
and changes the notifications to be rounded rather than squared.
2017-04-25 17:47:36 -07:00
Tim Abbott
faf47fe147 lint: Fix gitlint checking commits in master but not in the branch.
This was causing a bunch of spurious failures.

Workaround for https://github.com/travis-ci/travis-ci/issues/4596 ;
TRAVIS_COMMIT_RANGE is actually just totally wrong for this purpose.
2017-04-25 16:52:52 -07:00
digi0ps
8fb9d2bff3 settings: Redesign settings/administration panel buttons.
This redesigns all the ugly bold-colored buttons in the settings and
administration pages.
2017-04-25 16:33:59 -07:00
Cory Lynch
0d9b77c8b7 composebox_typeahead.js: Add typeahead cancelling for '# '.
If somebody types '# ', then close the typeahead dialog and
don't autocomplete. Relevant node tests were also added.

Fixes #4505.
2017-04-25 15:55:23 -07:00
Tim Abbott
60225012e6 unread: Add tool for marking all messages as unread for testing.
This tool can save a lot of manual work in testing our unread counts
logic.
2017-04-25 15:40:12 -07:00
vbNETonIce
cb2181d42d Update prod-maintain-secure-upgrade.md
fixing typo in line 370: 'we should' > 'we show'
2017-04-25 15:25:22 -07:00
Tim Abbott
c0d7e83333 logging: Change missing push notification keys from error to warning.
This is a configuration problem, but it just means a feature is not
enabled, not that attention is required, so it should be a warning,
not an error.
2017-04-25 13:52:36 -07:00
Tim Abbott
b6094b8e91 logging_handlers: Fix missing host key in queue errors.
This fixes exceptions thrown when trying to report errors from queue
processors to email.
2017-04-25 13:48:44 -07:00
digi0ps
1cc9cb969b sidebar: Make topic name width consistent. 2017-04-25 11:58:33 -07:00
digi0ps
eb852ef19e sidebar: Move chevron in the stream list further from the scrollbar.
Previously, the chevrons were too close to the scrollbar. This commit
fixes that by moving it farther from the scrollbar.
2017-04-25 11:58:33 -07:00
Sarah
faf20d9b47 Documentation: Update new feature tutorial.
Update the steps listed in the "Writing a new application
feature" section, based on changes to how realm properties
are created and updated on the backend.

Addresses part of issue #3854.
2017-04-25 11:16:27 -07:00
Eeshan Garg
46b6475066 webhooks/gitlab: Use branches.find to filter Git notifications. 2017-04-25 10:46:21 -07:00
Eeshan Garg
8900e99ae5 github_webhook: Use branches.find to filter Git notifications. 2017-04-25 10:46:21 -07:00
Eeshan Garg
047c02781c webhook-walkthrough: Recommend passing kwargs to build_webhook_url.
When constructing URLs for testing, we now recommend passing
query parameters as keyword arguments to build_webhook_url
instead of overriding it.
2017-04-25 10:46:21 -07:00
Maxim Averin
15170b5423 Switch regenerate_api_key to use RealmAuditLog. 2017-04-25 10:23:33 -07:00
Steve Howell
8eb86335b9 Extract narrow_state.js.
Despite the length of this commit, it is a very straightforward
moving of code from narrow.js -> narrow_state.js, and then
everything else is just s/narrow.foo()/narrow_state.foo()/
(with a few tiny cleanups to remove some code duplication
in certain callers).

The only new functions are simple setter/getters that
encapsulate the current_filter variable:

    narrow_state.reset_current_filter()
    narrow_state.set_current_filter()
    narrow_state.get_current_filter()

We removed narrow.predicate() as part of this, since it was dead
code.

Also, we removed the shim for narrow_state.set_compose_defaults(),
and since that was the last shim, we removed shim.js from the app.
2017-04-25 09:57:32 -07:00
Steve Howell
7326971380 Extract stream_edit.js.
This code makes the right pane work in "Manage Streams" when
you are editing a stream subscription.  It handles basic
functionality (submitting forms, etc.), live updates, and
showing the pane as needed.

Most of the code here was simply moved from subs.js, but some
functions were pulled out of larger functions:

    live update:
        add_me_to_member_list
        update_stream_name
        update_stream_description

    collapse/show:
        collapse
        show_sub

We also now export subs.show_subs_pane.

We eventually want stream_edit not to call into subs.js, and
this should be fairly easy--we just need to move some shared
methods to a new module.
2017-04-25 09:57:32 -07:00
Steve Howell
ca2aea8d01 Extract stream_create.js.
This new modules handles the UI to create streams.  It mostly moves
code from subs.js.

It introduces an API around what used to be called meta.stream_created:

    reset_created_stream()
    set_name()
    get_name()

It only partially moves new_stream_clicked().
2017-04-25 09:57:32 -07:00
Umair Khan
86ebc2ccb1 testing: Reset INSTRUMENTED_CALLS for subsuites.
We need to reset INSTRUMENTED_CALLS variable before running every
subsuite. If we do not do this then the subsuite running on a
particular process called A will send the accumulated instrumented
calls gathered by the previous subsuites which also ran on the process A.

This also fixes the extra delay that we used to experience after the
tests had finished running. The extra delay was due to the duplicate
instrumented calls in the INSTRUMENTED_CALLS list. The size of this
list used to be ~100k for parallel model as opposed to ~1800 for serial
model.
2017-04-25 09:07:15 -07:00
Umair Khan
d4ca0f1751 testing: Create one upload directory per process.
This commit creates a dedicated file upload directory for every process
when we are running tests in parallel mode. This makes sure that we do
not run into any race conditions due to multiple processes accessing
the same upload directory.
2017-04-25 09:07:15 -07:00
Umair Khan
93b4200cae testing: Move _worker_id incrementer block to the top.
Incrementing the _worker_id should be the first step for the process.
It gives better structure to the code.
2017-04-25 09:07:15 -07:00
Tim Abbott
145fa0e5b2 capitalization: Flag Emoji One as allowed. 2017-04-24 23:15:39 -07:00
Tim Abbott
427629ca4c emoji: Fix strings in migration 0076.
It's arguably a bug that Django puts the value strings into the
migration object, but this was causing test failures.
2017-04-24 22:50:19 -07:00
Cynthia Lin
ef2ff9f9a0 integrations: Remove deprecated Stash integration. 2017-04-24 22:35:23 -07:00
Cynthia Lin
a267c61cdd integrations: Update docs for adding integration images. 2017-04-24 22:34:36 -07:00
Harshit Bansal
6cb03ea78e frontend: Add UI necessary to change emoji set.
Note that this code is disabled until the infrastructure for the
feature can be finished.

Tweaked by tabbott to use slightly cleaner names for the various sets.
2017-04-24 22:31:30 -07:00
Harshit Bansal
07081196f4 backend: Allow to change UserProfile's emojiset field via api. 2017-04-24 22:30:07 -07:00
Harshit Bansal
fb3fda031d models: Add emojiset field to UserProfile model.
Includes a database migration.
2017-04-24 22:30:06 -07:00
Tim Abbott
1f0c4e5fb3 email mirror: Fix mypy annotation error. 2017-04-24 22:01:48 -07:00
Umair Khan
556264f3d7 reset_password: Modify password reset email if email is in wrong realm.
This fixes a confusing issue where a user might try resetting the
password for an email account that in part of a different Zulip
organization.

Is a useful early step towards making Zulip support reusing an email
in multiple realms.

Fixes: #4557.
2017-04-24 21:58:29 -07:00
Emilio Aburto L
a8521dc988 docs: Update Docker development instructions to include chown.
This adds a command to change ownership of /srv/zulip to the zulip
user.
2017-04-24 21:40:44 -07:00
K.Kanakhin
e3e52e7284 email-mirror: Move postfix email mirror integration to separate script.
This fixes a performance problem where we were previously starting up
a full Django process (~0.7s even on a fast machine) every time a new
email came in, potentially allowing users to accidentally DoS a Zulip
server.  Now, we just post over HTTPS, allowing the existing thread
pool support to do its job.

- Add script wrapper to communicate postfix pipe with django web server
  over HTTP(S). It uses shared_secret authentication mode.
- Add django view to process messages from email mirror server.
- Clean management command `email-mirror`. Left just functional
  for cron email processing.
- Add routes for new tornado view.
- Change pipe script in master process postfix config template
  based on updated script.
- Add tests.

Tweaked by tabbott to adjust the directory and set better defaults.

Fixes #2421.
2017-04-24 21:24:23 -07:00
Brock Whittaker
ba51c077be Add assets for portico signin pages.
This adds some of the required assets for the portico signin pages such
as logos and validation signals.
2017-04-24 16:19:18 -07:00
Steve Howell
232e1e4006 minor: Tweak js-dep-visualizer configuration. 2017-04-24 14:46:34 -07:00
wangjames
744f4aa663 Fix modals dependency cycle.
This commit forces the files that create modals to create their own
modal closing function instead of creating all of them in the modals
file. These functions are then passed to the modals.close object. This
is intended to remove modals.js's dependencies on these other files.
2017-04-24 14:30:02 -07:00
Steve Howell
c999bdf823 compose: Distinguish get_message_type() from composing().
We now only call compose_state.composing() in a boolean context,
where we simply care whether or not the compose box is open.  The
function now also returns true/false.

Callers who need to know the actual message type (e.g. "stream" or
"private") now call compose_state.get_message_type().
2017-04-24 12:42:06 -07:00
derAnfaenger
2adf641b72 Fix provisioning failing due to partial downloads.
'$COMMIT' was originally printed in '$COMMIT_FILE_PATH' before all
respective files were downloaded, meaning that this step
wouldn't be repeated if one download failed. This commit prints
'$COMMIT' only after all downloads were successful.
2017-04-22 21:16:11 -07:00
Tommy Ip
a67ade2419 lint: Fix gitlint test due to non-deterministic git range.
This makes getting the commit SHA non time sensitive by using the
range provided by TravisCI.
2017-04-22 21:34:58 +01:00
Steve Howell
5ae284dcb1 Add topic_generator.js to the app. 2017-04-22 11:46:47 -07:00
Steve Howell
d938afaedc Extract narrow.narrow_to_next_topic().
This borrows some code from a PR from Mahim Goyal.
2017-04-22 11:46:47 -07:00
Maxim Averin
73a1dd63d5 analytics: Refactor legacy 'zulip_internal' decorator.
Rename 'zulip_internal' decorator to 'require_server_admin', add
documentation for 'server_admin', explaining how to give permission
for ./activity page.

Fixes: #1463.
2017-04-22 11:42:02 -07:00
Tommy Ip
6ec32b37c3 lint: Fix lint rule error due to unordered list.
Tweaked to automatically sort by tabbott.
2017-04-22 11:38:36 -07:00
Eeshan Garg
ce0f1453b9 webhooks: Filter specific BitBucket Git branches.
This is the last of the Git integrations that didn't have this
feature.

Fixes #4327.
2017-04-22 11:29:53 -07:00
Shayan Toqraee
534c951ec4 Add rtl.js library for detecting direction of text.
This comes complete with some documentation and node tests, and is a
key step towards implementing RTL support in Zulip.
2017-04-22 11:25:54 -07:00
Michael
854d70e7c6 test_events: Verify format of event dicts precisely.
This is basically just using the new check_dict_only everywhere, with
a few exceptions:
* New self.check_events_dict automatically adds the id field to avoid
  duplicating it ~80 times.
* Set log=False for many of the testing action functions to remove the
  timestamp field from their returned event dictionaries, since it's
  not needed and is the result of a deprecated log_event function.

Wasn't sure if the subscription_field list in do_test_subscribe_events
could contain optional arguments, so I left the call to check_dict on
along with a TODO.

Fixes: #1370.
2017-04-22 11:22:41 -07:00
hackerkid
a768c94f9d requirements: Upgrade django-bitfield to 1.9.2. 2017-04-21 22:25:50 -07:00
Steve Howell
ddbe877909 Add narrow.stream_topic(). 2017-04-21 21:59:22 -07:00
Steve Howell
6ddbf12376 Add topic_generator.get_next_topic(). 2017-04-21 21:59:22 -07:00
Steve Howell
079885770b Add unread.topic_has_any_unread(). 2017-04-21 21:59:22 -07:00
Steve Howell
4871b491f3 Add Dict.is_empty(). 2017-04-21 21:59:22 -07:00
Steve Howell
b27180a645 Have next_topic() return stream/topic objects.
We now use "map" to have our inner generator of topics be
mapped to objects with both the stream and topic.  Thanks to
Mahim Goyal for helping with this design.
2017-04-21 21:59:22 -07:00
Steve Howell
d332df8cc6 Add topic_generator.map(). 2017-04-21 21:59:22 -07:00
Aditya Bansal
bdcddd35d0 tests: Add wrapper for client.logout in ZulipTestCase.
In this commit we add a logout wrapper so as to enable developers
to just do self.logout instead of doing a post request at API
endpoint for logout. This is achieved by adding a wrapper function
for the Django's client.logout contained in TestCase. We add this
by extending ZulipTestCase to have a logout function.
2017-04-21 21:45:55 -07:00
hackerkid
cf001876d4 Increment provision version to upgrade python dependencies. 2017-04-21 18:13:58 -07:00
hackerkid
0689954373 requirements: Upgrade zope.interface to 4.4.0. 2017-04-21 18:13:58 -07:00
hackerkid
7db87a452c requirements: Upgrade typing to 3.6.1. 2017-04-21 18:13:58 -07:00
hackerkid
60d3346369 requirements: Upgrade SQLAlchemy to 1.1.9. 2017-04-21 18:13:58 -07:00
hackerkid
8ca2ed1ce2 requirements: Upgrade Werkzeug to 0.12.1. 2017-04-21 18:13:58 -07:00
hackerkid
05a5a8bc40 requirements: Upgrade tornado to 4.5.1. 2017-04-21 18:13:58 -07:00
hackerkid
0707c8a58b requirements: Upgrade tblib to 1.3.2. 2017-04-21 18:13:58 -07:00
hackerkid
8d6ed0419c requirements: Upgrade sphinx-rtd-theme to 0.2.4. 2017-04-21 18:13:58 -07:00
hackerkid
12367a7580 requirements: Upgrade Sphinx to 1.5.5. 2017-04-21 18:13:58 -07:00
hackerkid
2f6d191ab8 requirements: Upgrade Scrapy to 1.3.3. 2017-04-21 18:13:58 -07:00
hackerkid
c5de115a51 requirements: Upgrade regex to 2017.4.5. 2017-04-21 18:13:58 -07:00
hackerkid
c9ee2b0c25 requirements: Upgrade pytz to 2017.2. 2017-04-21 18:13:58 -07:00
hackerkid
97563b4061 requirements: Upgrade pyOpenSSL to 17.0.0. 2017-04-21 18:13:58 -07:00
hackerkid
1ff9d6a600 requirements: Upgrade pylibmc to 1.5.2. 2017-04-21 18:13:58 -07:00
hackerkid
d8965691a4 requirements: Upgrade PyJWT to 1.5.0. 2017-04-21 18:13:58 -07:00
hackerkid
f68f898fc5 requirements: Upgrade prompt_toolkit to 1.0.14. 2017-04-21 18:13:58 -07:00
hackerkid
6b94cdc6f0 requirements: Upgrade Pillow to 4.1.0. 2017-04-21 18:13:58 -07:00
hackerkid
a9af3df67f requirements: Upgrade pbr to 3.0.0. 2017-04-21 18:13:58 -07:00
hackerkid
2929c15953 requirements: Upgrade oauthlib to 2.0.2. 2017-04-21 18:13:57 -07:00
hackerkid
5972679a50 requirements: Upgrade MarkupSafe to 1.0. 2017-04-21 18:13:57 -07:00
hackerkid
8b126cbb22 requirements: Upgrade Jinja2 to 2.9.6. 2017-04-21 18:13:57 -07:00
hackerkid
1600337e4e requirements: Upgrade ipython-genutils to 0.2.0. 2017-04-21 18:13:57 -07:00
hackerkid
b2db6f05fd requirements: Upgrade fonttools to 3.10.0. 2017-04-21 18:13:57 -07:00
hackerkid
28c704db01 requirements: Upgrade Flask to 0.12.1. 2017-04-21 18:13:57 -07:00
hackerkid
cf6cd3a447 requirements: Upgrade django-pipeline to 1.6.12. 2017-04-21 18:13:57 -07:00
hackerkid
0999227648 requirements: Upgrade django-auth-ldap to 1.2.10. 2017-04-21 18:13:57 -07:00
hackerkid
72b1db5920 requirements: Upgrade cryptography to 1.8.1. 2017-04-21 18:13:57 -07:00
hackerkid
afc835a91e requirements: Upgrade chardet to 3.0.2. 2017-04-21 18:13:57 -07:00
hackerkid
0915171868 requirements: Upgrade cffi to 1.10.0. 2017-04-21 18:13:57 -07:00
hackerkid
91011b74ef requirements: Upgrade certifi to 2017.4.17. 2017-04-21 18:13:57 -07:00
hackerkid
276ef60241 requirements: Upgrade cchardet to 2.0.0. 2017-04-21 18:13:57 -07:00
hackerkid
297964a0c1 requirements: Upgrade Babel to 2.4.0. 2017-04-21 18:13:57 -07:00
hackerkid
fdbdd665eb requirements: Upgrade alabaster to 0.7.10. 2017-04-21 18:13:57 -07:00
Eeshan Garg
55e1154871 webhooks/beanstalk: Filter specific Git branches. 2017-04-21 22:06:11 -02:30
Eeshan Garg
dded73ec6f webhooks: Stop overriding build_webhook_url for URL query parameters. 2017-04-21 22:06:11 -02:30
Eeshan Garg
e68b957f3d webhooks/gogs: Filter specific Gogs branches. 2017-04-21 22:06:11 -02:30
Tommy Ip
680e39ff55 linter: Add custom gitlint rule to check for imperative mood. 2017-04-21 15:43:19 -07:00
Yago González
43bc4cd762 formatting help: Remove unnecessary space. 2017-04-21 14:59:57 -07:00
Yago González
fac8d1a91d formatting help: Add documentation for TeX math. 2017-04-21 14:59:57 -07:00
Joshua Pan
64984f5bf4 Rename tools/lint-all to tools/lint.
Fixes #4574.
2017-04-21 14:57:47 -07:00
Tim Abbott
f4a4c23380 KaTeX: Fix path to KaTeX bundle in production. 2017-04-21 14:56:19 -07:00
Tim Abbott
1883bff243 lint: Rename lint-commits to keep tab-complete fast. 2017-04-21 13:45:20 -07:00
Tommy Ip
ec8e47192a lint: Add checks for commit messages using gitlint.
Fixes #1131.
2017-04-21 13:45:12 -07:00
Tim Abbott
7d8d9c1bf9 Fix message-edit animations being displayed after sending.
This fixes a regression in 3041480600
that would cause anything rendered on the backend differently than on
the frontend to experience this animation.

We actually only want to do the animation when the message content was
changed in a way that generates an edit history event, i.e. a
user-facing edit, not in cases where we're either transparently
swapping in post-backend-rendering content (e.g. with link previews)
or cases where there's a discrepancy between the exact HTML from the
frontend and backend markdown processes (e.g. mentions).
2017-04-21 11:46:35 -07:00
Tim Abbott
e7974b3b65 git: Fix nondeterministic ordering of commit authors.
This should fix the nondeterministic test failures introduced by
e7455e276b.
2017-04-21 11:45:30 -07:00
Siddharth Mahapatra
e7455e276b git integrations: Expand details in commit push notifications.
We now show a few new things:
(1) The number of commits pushed.
(2) Who authored the commits (just counts, not which specific ones, for brevity).

Add tests for case of multiple committers.

Part of #3968.
2017-04-21 11:07:44 -07:00
Joshua Pan
11878313fb docs: Tweak reset-to-pull-request warning.
Tweaked this warning because we currently check if there are any
uncommited changes before we reset to a specific pull request.

Changes expanded a bit by tabbott.
2017-04-21 10:12:04 -07:00
Steve Howell
cc6c0104c8 Refine compose box behavior for topic narrows.
The comments that were added in the code for this commit explain
the cases here, but essentially for topics, we need to decide
among a few possible behaviors with regard to composing:

- Leave it closed.
- Cancel the compose.
- Leave the compose box as it was before.
- Fill in the new topic.

Before this commit, we were cancelling compose in all cases (or
leaving it closed).

Now we leave it alone in some cases where there is already content.
And we fill in the topic when the stream was correct and the topic
was empty.

Fixes #3300
2017-04-20 16:15:07 -07:00
Tim Abbott
21c4be3f00 chat-zulip-org: Document learning stream. 2017-04-20 16:04:42 -07:00
Tim Abbott
b3c8562bd9 css: Remove use of under-specified 'thin' borders.
This was causing buggy behavior in our emoji reactions when zoomed to
200%.
2017-04-20 15:07:26 -07:00
Tim Abbott
f3c36147d9 /me: Fix alignment of name with non-/me messages. 2017-04-20 14:58:22 -07:00
Brock Whittaker
83d51b2bdb Hide status message on edit.
When editing a /me, the status message element should be hidden.
2017-04-20 14:36:17 -07:00
Brock Whittaker
323ff6edca /me: Fix presentation and markup for /me statuses.
This fixes the /me elements to be display inline-block and inline
rather than display block with top and left properties.

This also fixes an unrelated issue with emoji reactions not being
able to be clicked on with /me messages.

Fixes: #4218.
2017-04-20 14:36:17 -07:00
Tim Abbott
1cfebdcb84 forms: Fix minor pep-8 lint error. 2017-04-20 11:39:19 -07:00
Umair Khan
dbbc73837d redirect_to_main_site: Handle is_signup parameter.
Passes on the is_signup parameter passed in a querystring.
2017-04-20 11:14:28 -07:00
Umair Khan
8b88cfc84b redirect_and_log_into_subdomain: Handle is_signup. 2017-04-20 11:11:54 -07:00
Umair Khan
4ab783134e testing: Move unsign_subdomain_cookie to test_helpers.
We'll be using it in other files soon.
2017-04-20 11:10:56 -07:00
Umair Khan
8fee31f7ff forms.py: Include email in the error messages. 2017-04-20 11:07:01 -07:00
Umair Khan
1d9113d326 forms.py: Use .format() for string formatting. 2017-04-20 10:28:05 -07:00
Joshua Pan
728594c74a activity.js: Stop opening compose box in user search.
This prevents compose box from opening when you
just press enter with an empty search field in
user search.

Fixes #4376.
2017-04-19 22:18:08 -07:00
Brock Whittaker
3041480600 message-edit: Fade in message on update.
When a message update comes back from the server and replaces an
old message, it should fade in. There are two components to the fade:

1. The message fades in from opacity: 0 =>  1.
2. The "edited" text will transform from X: -10 => X: 0.
2017-04-19 22:14:58 -07:00
Sarah
81f76ff13b Realm.py: Removing 'exclude' variable.
The exclude variable was superfluous. The realm properties
listed in the exclude variable are not in the
realm.property_types dict, so they do not need to
be explicitly excluded.
2017-04-19 22:08:36 -07:00
Sarah
95ff65b290 zerver/lib/events: Refactor fetch_initial_state_data.
This Refactors the function fetch_initial_state_data to use the
realm.property_types attribute, avoiding some unnecessary code
duplication.

Tweaked slightly by tabbott to simplify the code a bit.

Addresses part of issue #3854.
2017-04-19 22:08:03 -07:00
Feorlen
6ff78ca0e8 Set umask 022 before starting prod upgrade.
Follow-on from #2373/ PR https://github.com/zulip/zulip/pull/4316, to set an
appropriate umask also when upgrading so files have appropriate permissions.

I've tested this by starting from a clean install, deleting /srv/* so new
files are downloaded, and then doing an upgrade. It worked starting with both
a current version from master and an older release installed with a less
restrictive umask and then the umask changed.

Fixes #2373.
2017-04-19 10:28:06 -07:00
Steve Howell
c7a9a02667 Consolidate code for narrow/compose interactions.
This commit extracts the method compose_actions.on_narrow()
to handle changing the compose box (as appropriate) after
any narrowing action.

This change should be mostly non-user-facing, but it's not
exactly a trivial extraction.

For the case where the user already had content in their
compose box, we continue to leave the compose box alone,
but we now update compose fading 150+ lines later in
narrow.activate().

Likewise, for cases where we cancel composing, this will
also happen later in the function.

Finally, for PM narrows, where we auto-open the compose box, we
no longer call compose.cancel() before calling compose.start(),
because either a) the compose box would have not been open
in the first place or b) the start() function can handle
clearing the old fields.
2017-04-19 10:06:00 -07:00
Tim Abbott
55bea73035 Revert "github: Call the appropriate authenticate."
This reverts commit ab260731a9.

The overridden authenticate method was buggy.
2017-04-19 10:06:00 -07:00
Tim Abbott
326cf9a73e stream_list: Add divider before dormant streams in list.
Fixes #4309.
2017-04-19 09:18:29 -07:00
Steve Howell
7962710132 Remove 40-streams criterion for flagging dormant streams.
Before this change, we would move "dormant" streams to the bottom
of your stream sidebar, but only if you had 40+ streams.

Now we do this in all cases to be more consistent.

This commit also changes the redraw strategy when we remove rows.
Before this change, we were doing incremental updates, but now we
call build_stream_list to do a complete rebuild.  This was partly
motivated by adding the new divider, which would have complicated
the incrememental approach when you removed the last remaining
dormant stream.
2017-04-19 09:18:18 -07:00
Steve Howell
9591b3a95b Extract stream_sort.js. 2017-04-19 09:16:37 -07:00
Joshua Pan
4fb450d4a9 hotkey.js: Add reactions popover navigation.
Fixes #4197.
2017-04-18 23:25:45 -07:00
Joshua Pan
a7327422a8 reaction.js: Create reaction_navigate(). 2017-04-19 06:17:15 +00:00
Joshua Pan
abda711c66 reaction.js: Extract reaction_show_list functions.
This creates get_emoji_at_index() and
find_index_for_emoji() functions, which search for
emojis and indices in reactions_show_list. Update
maybe_select_emoji with newly created functions.
2017-04-19 06:17:15 +00:00
Joshua Pan
e075c84ca5 reaction.js: Maintain reaction_show_list.
This updates reaction_show_list whenever the popover
gets opened and whenever the search filter for reactions
gets used.
2017-04-19 06:17:15 +00:00
Joshua Pan
cd28ea6d07 reaction.js: Update toggle_reaction().
Created get_selected_emoji() function.
toggle_reaction() now doesn't require emoji_name
and automatically looks for a selected_emoji
if possible.
2017-04-19 06:16:30 +00:00
Tim Abbott
cddee49e75 Add support infrastructure for push notification bouncer service.
This is an incomplete cleaned-up continuation of Lisa Neigut's push
notification bouncer work.  It supports registration and
deregistration of individual push tokens with a central push
notification bouncer server.

It still is missing a few things before we can complete this effort:
* A registration form for server admins to configure their server for
  this service, with tests.
* Code (and tests) for actually bouncing the notifications.
2017-04-18 23:03:06 -07:00
Tim Abbott
ae788b2e98 zilencer: Remove decorators Deployment code. 2017-04-18 23:00:10 -07:00
Tim Abbott
cd89fbc0a9 models: Extract AbstractPushDeviceToken. 2017-04-18 23:00:10 -07:00
Tim Abbott
55a9101573 settings: Add support for ZULIP_ORG secrets.
These can be used to authenticate the current Zulip server to
zulip.org.
2017-04-18 23:00:10 -07:00
Tim Abbott
540bfce83f reactions: Use perfectScrollbar for emoji reactions scrollbar.
This fixed the fact that the scrollbar for this popover was super ugly
on Linux, while also ensuring that we have a consistent 6 emoji per
row in the popover (an important detail for the arrow hotkeys).
2017-04-18 22:58:11 -07:00
Joshua Pan
c6d0e49cdf Add tabindex to reaction popover content handlebars. 2017-04-18 22:31:08 -07:00
Umair Khan
8f5dfffe39 testing: Fix test_update_invalid_value.
This test was using hardcoded field id which made it order dependent.
2017-04-18 21:46:14 -07:00
Jacob Hurwitz
8343d80873 Fix mobile home view returning messages older than the pointer.
In cases where old unread messages in the home view might have been
leaked (either due to bugs or unusual muting interactions), it's
theoretically possible for the first unread message in the home view
to be far older than the pointer.

Since the Zulip mobile app is loading messages following the
use_first_unread logic, we need to plug this gap.

Probably a longer-term solution will involve changing how
update_message_flags works to automatically advance the pointer, but
this change should make it possible for the mobile apps to
consistently use the `use_first_unread` mechanism for fetching the
latest home view messages.

With tweaks to the tests by tabbott.

Fixes zulip/zulip-mobile#422.
2017-04-18 21:39:24 -07:00
Tim Abbott
6d9962851c renumber_migrations: Strip trailing '.py' from migrations.
This fixes a bug when renumbering more than 1 migration at a time.
2017-04-18 21:31:17 -07:00
Tim Abbott
c6cd7074ee renumber-migrations: Mark as executable. 2017-04-18 21:27:29 -07:00
Tim Abbott
a543b3cacd attachment: Clarify and test logic for invalid uploads. 2017-04-18 21:27:29 -07:00
Tim Abbott
e90748348b attachment: Remove unused claim_attachment return value. 2017-04-18 21:27:29 -07:00
Tim Abbott
568b59291b attachment: Improve rules for managing attachment ownership.
The previous logic was that anyone with a link to a file could send it
to other users, but only the owner could make a file realm-public.
This had some confusing corner cases.

The new logic is much simpler:
* Only the file's owner/uploader can include a file in a message for
  the first time.
* Anyone with access to read a file can share it with others by
  including it in messages they send.
* Once a file has been sent to a public stream, any user in the realm
  can access it.
2017-04-18 21:27:29 -07:00
Tim Abbott
b92385ea8e attachment: Make path_id field unique.
This will help avoid future bugs similar to that fixed in migration
0072.
2017-04-18 21:27:28 -07:00
Tim Abbott
0f855b84cc attachment: Add migration to fix duplicate attachment objects.
The comment in the migration explains this change in detail.
2017-04-18 21:27:27 -07:00
Aditya Bansal
08e4a67fa5 tests: Fix occasionally breaking tests.
In this commit we fix the occasionally breaking tests for
test_home.HomeTest.test_bad_narrow which were the result of
us patching global settings in test_upload to add some new emails
to CROSS_REALM_BOT_EMAILS and not rolling back.
2017-04-18 19:44:12 -07:00
Abhijeet Kaur
5e55fe992d backend: Add ability to search by group private message thread.
This doesn't yet contain the frontend or documentation for this
feature.

Modified by tabbott to rename the parameter and line-wrap the query
code.
2017-04-18 15:50:27 -07:00
Steve Howell
cf4b08f0cf minor: Update dependency tool configuration. 2017-04-18 15:28:08 -07:00
Umair Khan
cf3b6c6ca9 profile: Support custom profile data.
Implements backend for #1760.
2017-04-18 15:20:59 -07:00
Umair Khan
d0f907f9da Make FindMyTeamForm strings translatable. 2017-04-18 15:13:25 -07:00
Kouhei Sutou
2f09866364 message: Support highlight in link tag.
textsearch based full text search doesn't match text in link tag but
PGroonga based full text search can match text in link tag.

Without this change, highlighting text in link tag generates broken
HTML.
2017-04-18 13:15:48 -07:00
Harshit Bansal
09c521d9e8 build_emoji: Use ujson.load() instead of json.load().
Use `ujson.load()` to load `emoji_map.json` and `emoji.json` as
it is faster than `json.load()`.
2017-04-18 13:00:46 -07:00
Harshit Bansal
c70cfa2188 build_emoji: Generate CSS files for all the emoji sets.
Modify the `build_emoji` tool to copy spritesheets for all the
emojisets to emoji cache and generate CSS files for them.
2017-04-18 13:00:46 -07:00
Harshit Bansal
e52f2b5aba download-emoji-data: Download sprite sheets for the remaining emoji sets.
Modify the `download-emoji-data` tool to download the sprite sheets
for all the currently supported emoji sets(apple, emojione, google
and twitter).
2017-04-18 13:00:46 -07:00
Harshit Bansal
5674e63fc3 Download iamcal's sprite sheets during provisioning and generate CSS files.
Add code to download iamcal's sprite sheets and generate CSS files required
for displaying these sprite sheets using emoji's unicode codepoints rather
than their names.
2017-04-18 13:00:46 -07:00
Harshit Bansal
d617fa8d81 emoji: Only include universal emoji in catalog.
Extracted from "Interrelated emoji infrastructure changes." by
tabbott.
2017-04-18 13:00:16 -07:00
Harshit Bansal
660d96038a build_emoji: Add emoji_catalog to emoji_code.js
Use `emoji.json` to create a emoji catalog and add it to
`emoji_code.js` file. This catalog contains the unicode
codepoints of all the emojis grouped according to their
category. Emojis are sorted according to the `sort_order`
defined in the iamcal's dataset.
2017-04-18 12:46:52 -07:00
Harshit Bansal
4470a3947b provision: Download emoji-data during provisioning.
Add code to download iamcal's emoji_pretty.json
(emoji-data/emoji.json) during provisioning.
2017-04-18 12:46:52 -07:00
Ayush Jain
518d25a0cf Disable proxy setting for test-backend and test-js-with-casper.
This fixes the fact that our test suites would have trouble connecting
to the other parts of the Zulip service when run with a proxy
configuration (e.g. trying to send requests to localhost through the
proxy!).

Thanks for Vishnu Ks for his work on this.

Fixes #971.
2017-04-18 12:35:44 -07:00
Steve Howell
70b7d4c00b Extract compose_state.js.
This is mostly just moving methods out of compose.js.

The variable `is_composing_message`, which isn't a boolean, has
been renamed to `message_type`, and there are new functions
set_message_type() and get_message_type() that wrap it.

This commit removes some shims related to the global variable
`compose_state`; now, `compose_state` is a typical global
variable with a 1:1 relationship with the module by the same
name.

The new module has 100% line coverage, most of it coming
via the tests on compose_actions.js.  (The methods here are
super simple, so it's a good thing that the tests are somewhat
integrated with a higher layer.)
2017-04-18 12:26:58 -07:00
Tejas Kasetty
7e4155cd42 update_emojis: Handle the case involving deletion of realm emoji. 2017-04-18 12:18:52 -07:00
Tejas Kasetty
d227a8e35c compose: Re-render emoji picker when realm_emoji is added/deleted.
* reset the emoji popover in case of an event
regarding update of realm_emoji.
* test-node-with-js: Add dependency - popovers module;
In dispath.js to support popovers object.
2017-04-18 12:18:52 -07:00
Tejas Kasetty
b7aa81f122 compose: Render the emoji picker only once.
* Whenever the emoji picker is opened a call is made to render
  the emoji's. This rendering happend everytime the emoji picker
  was opened. Thus, resulting in duplicates of emoji's getting
  appended in the emoji picker over multiple open and close.

* This commit, is a fix to render the emoji's only once when the
  emoji picker is opened for the first time. Further calls just
  toggles the emoji picker showing the already rendered emoji's.
  This enhances the performance of Emoji picker considerably
  because there is no overhead of making a request to get the emoji's
  from the server, each time the emoji picker is opened.

* Other changes -- on closing the emoji picker, the compose box
  remains in focus.

Fixes: #4300.
See Also: #3952.
2017-04-18 12:18:52 -07:00
Joshua Pan
6fe567846c Extract drafts_scroll() function.
Fixes #4334.
2017-04-18 12:14:41 -07:00
Joshua Pan
0377b5aba6 Extract drafts_initialize_focus().
This function takes care of focusing a draft if a draft
is not already focused in draft modal.
2017-04-18 12:14:41 -07:00
Joshua Pan
6fe26b6c04 Extract drafts process enter key to drafts.js.
Extracted draft code from hotkey.process_enter_key to drafts.js.
2017-04-18 12:14:41 -07:00
Aditya Bansal
065dd9ae10 Clean emoji-settings-admin.handlebars to use 4 space indents. 2017-04-18 12:06:31 -07:00
Aditya Bansal
1f09e38101 Clean bot-settings.handlebars to use 4 space indents. 2017-04-18 12:06:30 -07:00
Aditya Bansal
c12f93efc4 Clean stream_privacy.handlebars to use 4 space indents. 2017-04-18 12:06:28 -07:00
Aditya Bansal
c98cf5ba63 Clean message_edit_history.handlebars to use 4 space indents. 2017-04-18 12:06:28 -07:00
Aditya Bansal
23f8ec9759 Clean single_message.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
5f7c89b087 Clean stream_sidebar_row.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
83da92c316 Clean recipient_row.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
0494944f3f Clean draft.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
face3562af Clean subscription_settings.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
bdcff375ab Clean deactivated-users-admin.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
4c1b89a2ef Clean attachment-item.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
e5d57c31b8 Clean muted-topics-settings.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
2a15fa17b9 Clean admin_auth_methods_list.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
c0ca8b10ed Clean deactivation-stream-modal.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
0e906b683d Clean realm-domains-modal.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
257b930492 Clean admin-realm-domains-list.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
e21731c1ae Clean streams-list-admin.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
71c5444b86 Clean alert-word-settings.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Aditya Bansal
b11866c2a8 Clean message_edit_form.handlebars to use 4 space indents. 2017-04-18 12:06:25 -07:00
Rishi Gupta
5e49da9285 analytics: Only update daily stats on day boundaries.
Previously we would update FillState for daily stats on hourly boundaries as
well. This would create two extra queries on the FillState table every hour
(for each CountStat), which adds roughly 50ms of extra processing for each
CountStat each day, as well as two extra lines each hour in the analytics
log. This can be a minor annoyance when backfilling stats.
2017-04-18 11:02:51 -07:00
Rishi Gupta
2535f6c8f2 docs: Remove CountStat description from analytics.md.
It is no longer correct, as of the string of commits ending in 49bd330.
2017-04-18 11:02:51 -07:00
Rishi Gupta
c5f1398052 analytics: Add section comments in counts.count_stats_.
Also reorders the stats a bit.
2017-04-18 11:02:51 -07:00
Rishi Gupta
b335ad2794 models: Add MIN_INTERVAL_LENGTH to UserActivityInterval.
Was previously a floating magic number appearing in both
zerver/lib/actions.py and analytics/lib/counts.py.
2017-04-18 11:02:51 -07:00
Tim Abbott
cbc731963f decorator: Add support for Django internal_notify_view. 2017-04-18 09:59:07 -07:00
Umair Khan
d699172d06 authenticate_remote_user: Properly handle None email. 2017-04-18 09:33:03 -07:00
Umair Khan
ea0288c4d0 testing: Create DB only in init_worker for parallel mode.
This commit has no bearing on serial mode performance. For parallel
mode, this will reduce the overhead of one instance of DB
destruction/creation.
2017-04-18 09:10:38 -07:00
Umair Khan
740a6c8081 test_runner.py: Add a docstring to init_worker(). 2017-04-18 09:08:17 -07:00
Steve Howell
78803b2e56 Add narrowed_by_topic_reply() helper. 2017-04-17 22:54:36 -07:00
Steve Howell
9d4f0bf704 Open compose box more aggressively for PM narrows.
We now auto-open the compose box whenever somebody narrows to
a "pure" PM narrow.  We already did this for buddy list clicks,
so this make it work the same for other ways of narrowing to
PM conversation.  Here, we optimize for composing, vs. reading,
since PM conversations tend to have lots of back and forth.

(Contrast this to stream conversations, where there's a higher
likelihood of lurking or doing a quick narrow to re-read some
message from the stream.)
2017-04-17 22:54:36 -07:00
Steve Howell
58aedf985f capser: Close the compose box in un_narrow(). 2017-04-17 22:54:36 -07:00
Steve Howell
bdca28a14b Avoid opening compose box for topic sidebar clicks.
We don't want to auto-open the compose box for topic
sidebar clicks, because we want to convenience folks
reading messages, not writing messages, since on
stream narrows, people tend to do much more reading
than writing.  (Also, opening the compose box explicitly
is super easy.)

The part of this change that affects behavior is that
we remove the call to compose_actions.start('stream').

Then the simplification is that we replace the checks
to narrowed_by_reply() and !narrowed_to_topic() with
a single call to narrowed_by_pm_reply().

Fixes #3886.
2017-04-17 22:54:36 -07:00
Steve Howell
af887822b5 Add narrowed_by_pm_reply() helper. 2017-04-17 22:54:36 -07:00
Italo Batista
d77d7dc493 analytics: Add a 'me' option for messages_sent_over_time.
With some tweaked by Rishi Gupta.

Fixes #3630.
2017-04-17 22:18:24 -07:00
Tim Abbott
1fe8df10f0 context: Include realm name, icon, and description.
This will be used in our upcoming login/registration page redesign.
2017-04-17 22:15:51 -07:00
Tim Abbott
cf2897d758 test_home: Fix test_handlebars_compile_error mock request.
Using a MagicMock for the request caused weird problems with invalid
input in the context processors.
2017-04-17 22:15:46 -07:00
Tim Abbott
8ae052a9d8 populate_db: Set a description for the default realm. 2017-04-17 21:59:21 -07:00
Cynthia Lin
2e1d9b7e95 modals: Document nested list bullets in Message formatting modal. 2017-04-17 21:51:14 -07:00
Cynthia Lin
0e6815fbf6 user docs: Document nested list bullets.
Fixes #4456
2017-04-17 21:51:14 -07:00
Cynthia Lin
619238ecf8 integrations: Strip metadata from integration logos to reduce file size. 2017-04-17 21:37:19 -07:00
Cynthia Lin
1e8bd51608 integrations: Fix warped Zendesk logo.
Fixes #4523
2017-04-17 21:37:19 -07:00
Sarah
1a7f487260 Realm.py: Refactor and remove duplicate code.
Moved error handling to the beginning of the update_realm
function. Removed several if statements and replaced them with
a block of code that loops through realm properties and updates
them if an update has been sent through the request. Also
created an 'exclude' list for realm properties that do not fit
into the general pattern that most other realm properties
follow for updating. Those properties are handled separately.

Some comments added by tabbott.

Addresses part of issue #3854.
2017-04-17 21:30:11 -07:00
Umair Khan
ab260731a9 github: Call the appropriate authenticate.
This commit makes sure that GitHubAuthBackend will only authenticate
using its own authenticate method. This is done by adding a new
Python Social Auth strategy which instead of calling authenticate
method of Django, calls the authenticate of the backend directly.

The problem this commit solves is that while authenticating through
GitHub backend, we were ending up getting authenticated through
ZulipDummyBackend. This might happen because the default strategy used
by Python Social Auth calls the authenticate method of Django which
iterates over all the backends and tries the authenticate methods
which match with the function arguments. The new strategy this commit
adds calls the authenticate method of GitHub backend directly which
makes sense because we already know that we want to authenticate with
GithHub.

The actual problem of why we are ending up on ZulipDummyBackend is
still a mystery because the function arguments passed to its
authenticate method are different. It shouldn't be called.
2017-04-17 21:03:08 -07:00
Steve Howell
22e21cddcb admin/settings: Lazy-load Organization sections.
We now wait to load Organization sections until you
click on the section (or virtually click by using arrow
keys).

Some of the sections are coupled in terms of their setup,
so some sections will already be loaded if you had clicked
on a related section.
2017-04-17 20:55:42 -07:00
Raghav Jajodia
79e48dc222 test-migrations: Suggest 'renumber-migrations'. 2017-04-17 20:54:47 -07:00
Raghav Jajodia
014ec04620 docs: Update docs to include renumber-migrations tool. 2017-04-17 20:53:35 -07:00
Raghav Jajodia
6e1e045fd5 tooling: Add script to automatically renumber migrations.
Previously, if you have a branch with a new migration,
and you rebase onto master past someone else's migration,
you have to manually renumber your migration.

Add a script that automatically renumbers the migrations.
Fix #4257.
2017-04-17 20:53:35 -07:00
Sampriti Panda
0e3d694df8 bugdown: Use queue for processing of links in image previews.
Earlier, a stack was being used to go through the message and search
for links.  Because of this, in some cases the images were added to
the preview in reverse.  Using a queue will keep the image previews in
the same order as they appeared in the message.

Fixes #4453.
2017-04-17 20:48:16 -07:00
Steve Howell
eae91eab08 Fix internals of message_store.get_pm_emails().
We now make sure we get the email based off the user ids
in message.display_recipient.
2017-04-17 20:36:59 -07:00
Steve Howell
31e7472cdb Fix quirk with message_store.get_pm_full_names().
After Iago changed his email, you would see strings like
"You and Iago, Cordelia," which was a consequence of looking up
Iago's full name using his old email.  Now we use user ids
internally for the lookup.
2017-04-17 20:36:59 -07:00
Steve Howell
e9e1441217 Fix warnings related to email changes.
We now call people.pm_reply_user_string to populate
message.to_user_ids.  The old way of computing this used emails
instead of user ids, so if an email wasn't known, you'd get a
warning.
2017-04-17 20:36:59 -07:00
Benjamin Gilbert
a282cbb493 emails: Fix typo in spelling of "recognize". 2017-04-17 20:29:14 -07:00
Benjamin Gilbert
4775f55ca7 Fix spelling of "occurred" in various places. 2017-04-17 20:29:07 -07:00
Raghav Jajodia
6be6aec825 components: Add new css to text input fields. 2017-04-17 11:12:01 -07:00
Raghav Jajodia
d4e1f0a9a8 stream_filter: Add clear-search button to Search stream input field. 2017-04-17 11:12:01 -07:00
Raghav Jajodia
99f8750684 Refactor code associated with clear_search button.
Transfer css from right-sidebar.css to components.css to make it reusable.
The 'margin-bottom' property is removed from 'input-append' class as
it does not affect the styling of the element.
2017-04-17 11:12:01 -07:00
Diego Berrocal
b059f4202c Remove spaces between file types in editorconfig list.
This makes some editorconfig plugins not work. (At least the Emacs one
wasn't working).
2017-04-17 10:04:17 -07:00
Tim Abbott
0c8575e2dc user_settings: Disable bot access to several endpoints.
These settings have no effect on bots, so this change is mostly about
just avoiding confusion.
2017-04-16 13:14:59 -07:00
Rishi Gupta
e14c940ecc decorator: Add human_users_only decorator.
Applies it to presence.update_active_status_backend as an example of usage.
2017-04-16 12:51:23 -07:00
Tim Abbott
9400689f86 presence: Remove use of timezone.now(). 2017-04-16 12:32:57 -07:00
hackerkid
4c0a5cf7fb docs: Update code-style.md to reflect timezone import change. 2017-04-16 12:28:56 -07:00
hackerkid
5c8f011d66 Remove unused timezone import. 2017-04-16 12:28:56 -07:00
hackerkid
c4f0fa97a8 Replace timezone.make_aware with timezone_make_aware. 2017-04-16 12:28:56 -07:00
hackerkid
6ddee006bd Replace timezone.is_naive with timezone_is_naive. 2017-04-16 12:28:56 -07:00
hackerkid
9acc27c2f0 Replace timezone.get_current_timezone_name with timezone_get_current_timezone_name. 2017-04-16 12:28:56 -07:00
hackerkid
b2504084ab Replace timezone.now with timezone_now. 2017-04-16 12:28:56 -07:00
hackerkid
55c3d12078 Replace timezone.utc with timezone_utc. 2017-04-16 12:28:56 -07:00
Tim Abbott
c47dd65c14 Organization settings: Fix 'save changes' button on auth methods.
This shouldn't be shown for non-administrators.
2017-04-16 12:21:36 -07:00
Abhijeet Kaur
c9166581fe Organization settings: Update "organization settings" view-only support.
Remove "Save changes" button for non-administrator users.
2017-04-16 12:21:36 -07:00
Abhijeet Kaur
ddfdf0e4c6 Organization settings: "Filter settings" tab view-only support.
This changes the layout of "organization settings" for
non-administrators such that they can view "Filter settings".
("Actions" column and form to add a new filter are not available).

Fixes: #3636
2017-04-16 12:21:36 -07:00
Abhijeet Kaur
dc801eb5ed Organization settings: "Default streams" tab view-only support.
This changes the layout of "organization settings" for
non-administrators such that they can view "Default streams" ("Actions"
and the form to add new default stream is not visible).
2017-04-16 12:21:36 -07:00
Abhijeet Kaur
f1e966bfaa Organization settings: "Bots" tab view-only support.
This changes the layout of "organization settings" for
non-administrators such that they can view "Bots" ("Actions"
column is not made visible).
2017-04-16 12:21:36 -07:00
Abhijeet Kaur
3f0e33e498 Organization settings: "Users" tab view-only support.
This changes the layout of "organization settings" for
non-administrators such that they can view "Users" (Actions are not
visible).
2017-04-16 12:21:30 -07:00
Rishi Gupta
5e1c8e4532 docs: Update chat-zulip-org with instruction to use gender-neutral language. 2017-04-15 16:53:04 -07:00
Rishi Gupta
0554ec13e8 docs: Update code of conduct. 2017-04-15 16:53:04 -07:00
Abhijeet Kaur
2c88e073fc Organization settings: "Authentication methods" view-only support.
This changes the layout of "organization settings" for
non-administrators such that they can view Authentication methods.
2017-04-15 08:12:56 -07:00
Tim Abbott
cc51b459be admin: Show/hide menu items after setup.
This allows disabling of UI elements in cases like the authentication
methods checkboxes that are rendered during the setup method.
2017-04-15 08:12:55 -07:00
Yago González
e710110a9e i18n: Automatically strip Handlebars strings.
Some Handlebars strings contained whitespaces characters at their ends.
With this, such characters are removed, as well as multiple spaces
(like the ones produced by code indentation).

This also includes a couple of fixes that removes spaces that were
intentionally placed before/after the string to translate.
2017-04-14 17:37:25 -07:00
Yago González
31c92cdcbc refactor: Keep sub replacements' format uniform. 2017-04-14 17:37:25 -07:00
Tim Abbott
496158c2d7 popovers: Move historical notice to actions popover.
This is still kinda ugly, so may need further work, but it at least is
now in a per-message location, not a per-sender-block location.
2017-04-14 17:17:19 -07:00
Brock Whittaker
9576d5caef frontend: Implement list_render class.
This implements a list_render closure class that allows for
progressive, responsive rendering of long, scrollable lists, with
filtering support.

It isn't used, at present.
2017-04-14 14:52:50 -07:00
Brock Whittaker
5e1471f5a3 Add preview_node functionality to util.js.
This shows a preview of a node given a reference to it like:
<tag id=“id” class=“className”></tag>.

It's intended to be used for reporting errors that are introduced by
developers in features such as the upcoming progressive list rendering.
2017-04-14 14:42:16 -07:00
Brock Whittaker
f08c8b1c56 Fix settings page height issue.
The height of the settings page content is not quite as tall as the
settings page could allow which makes for an empty white space at the
bottom of the settings content container.
2017-04-14 14:38:45 -07:00
Rishi Gupta
b5482d51b1 presence.py: Change bot-related error messages to match each other. 2017-04-14 14:34:17 -07:00
Rishi Gupta
bbddbdeb25 presence.py: Enforce bots cannot use update_active_status_backend.
We need to keep the UserActivity table clean now that we're using it to
compute 15day actives in analytics.
2017-04-14 14:34:17 -07:00
Yago González
f62b8ea080 css: Properly wrap text inside tabs.
The tabs can have text inside them that is wider than 90px, especially
in some unexpected cases (e.g. a translation longer than the original
English string).

This type of tabs can be seen in the following popover menus:

 - Stream subscriptions
 - Help (with hotkeys, formatting info, etc.)
 - Settings

Now text wider than the tab is ellipsized so it doesn't cause any
problem with the rest of the layout, except in the help popover (where
it gets wrapped).
2017-04-14 14:15:37 -07:00
Raghav Jajodia
09090fa8a6 message_edit: Replace image tag with inline SVG tag for clipboard image. 2017-04-14 14:07:59 -07:00
Raghav Jajodia
ae48eaa90d single_message: Show "Copied!" success message after copying.
As the user clicks the "Copy and close" button, the message_edit
closes and a success message is shown for a few seconds.
2017-04-14 14:07:36 -07:00
Raghav Jajodia
2bb632824e message_edit: Modify css for hover over 'Copy' button.
Replace background-image of copy button with an image
and change color on hover.
2017-04-14 14:01:57 -07:00
Raghav Jajodia
fd5ad3658d message_edit: Only show "Copy" button for View Source/Topic-edit-only.
The "Copy" button will only be shown for "View Source"
or "Topic editing only". Also replaced "Copy to clipboard"
with "Copy and close" to make autoclose less surprising.

Fixes #4238.
2017-04-14 14:01:57 -07:00
Steve Howell
5ba79f9c3a refactor: Move respond/reply methods to compose_actions.js.
This moves respond_to_mention() and reply_with_mention() to
compose_actions.js.  These methods are basically thin layers
on top of compose_actions.start().
2017-04-14 13:09:19 -07:00
Steve Howell
09d2c42e0e Add unit tests for compose respond/reply. 2017-04-14 13:09:19 -07:00
Steve Howell
dd0c50f0df Extract compose_actions.js.
This module extracts these two functions that get called by
several other modules:

    start()
    cancel()

It is a little bit arbitrary which functions got pulled over
with them, but it's generally functions that would have only
been called via start/cancel.

There are two goals for splitting out this code.  The first
goal is simply to make `compose.js` have fewer responsibilities.
The second goal is to help break up circular dependencies.
The extraction of this module does more to clarify
dependencies than actually break them.  The methods start()
and cancel() had actually been shimmed in an earlier commit,
and now they no longer have a shim.

Besides start/cancel, most of the functions here are only
exported to facilitate test stubbing.  An exception is
decorate_stream_bar(), which is currently called from
ui_init.js.  We probably should move the "blur" handler out
of there, but cleaning up ui_init.js is a project for another
day.

It may seem slightly odd that this commit doesn't pull over
finish() into this module, but finish() would bring in the
whole send-message codepath.  You can think of it like this:

* compose_actions basically just populates the compose box
* compose.finish() makes the compose box do its real job,
  which is to send a message
2017-04-14 13:09:19 -07:00
Steve Howell
703074215a Export compose.abort_xhr(). 2017-04-14 13:09:19 -07:00
Steve Howell
254b9559da Export compose.clear_preview_area(). 2017-04-14 13:09:19 -07:00
Steve Howell
0bf6dafdc7 node tests: Add compose_actions.js. 2017-04-14 13:09:19 -07:00
Steve Howell
9bd096f3cf compose: Extract blur_textarea(). 2017-04-14 13:09:19 -07:00
Steve Howell
ec8bd077d1 compose: Extract clear_textarea(). 2017-04-14 13:09:19 -07:00
Rishi Gupta
49bd330304 analytics: Add class DependentCountStat and stat realm_active_humans::day. 2017-04-14 11:41:07 -07:00
Rishi Gupta
62de1cf898 test_counts: Modernize TestProcessCountStat tests. 2017-04-14 11:41:07 -07:00
Rishi Gupta
1e8d2b984d counts.py: Rename DataCollector-level operations to be more generic.
We're about to use these for DependentCountStats that will run SQL queries
on the analytics tables instead of the zerver tables.
2017-04-14 11:41:07 -07:00
Rishi Gupta
47cf1d15ba counts.py: Move performance logging call out of pull_functions.
Makes it less likely someone will write a pull function in the future and
forget.
2017-04-14 11:41:07 -07:00
Rishi Gupta
6dff22cbaf counts.py: Change check for LoggingCountStat to use isinstance.
I think this is more pythonic?

We could also get rid of LoggingCountStats altogether, since it's now just a
special case of CountStat (is_logging == data_collector.pull_function is None).
But I think it's nice to keep the distinction since they behave so differently.
2017-04-14 11:41:07 -07:00
Rishi Gupta
b45185562a counts.py: Fix out of date comments. 2017-04-14 11:41:07 -07:00
Rishi Gupta
ac2cc9e2da counts.py: Reorganize file into logical sections.
No changes to code or behavior.
2017-04-14 11:41:07 -07:00
Rishi Gupta
50868b98a9 counts.py: Change pull_function to take a property instead of a full stat.
Removes the circular dependency of CountStat containing a DataCollector, and
DataCollector containing a function that takes a CountStat as an argument.
2017-04-14 11:41:07 -07:00
Rishi Gupta
eadfc743c8 counts.py: Remove CustomPullCountStat. 2017-04-14 11:41:07 -07:00
Rishi Gupta
118b44d4f0 counts.py: Change DataCollector to take a pull_function argument.
This will allow us to appropriately generalize CountStat to include
LoggingCountStat and CustomPullCountStat. It'll also make life easier when
we introduce DependentCountStat.
2017-04-14 11:41:07 -07:00
Rishi Gupta
f9e56ad25d counts.py: Move DataCollector declarations into CountStat declarations.
The previous zerver_* names were unwieldy and not very readable. This also
puts more of the useful information in one place; in particular, makes it
easier to skim a CountStat declaration and see if we're collecting it at a
user/stream granularity or a realm granularity.
2017-04-14 11:41:07 -07:00
Rishi Gupta
c20e79ab1f counts.py: Rename DataCollector.analytics_table to output_table. 2017-04-14 11:41:07 -07:00
Rishi Gupta
6369d23633 counts.py: Rename ZerverCountQuery to DataCollector.
Not the final form of DataCollector, but the name change causes a big diff
so separating it out.
2017-04-14 11:41:07 -07:00
Rishi Gupta
b3991e2557 counts.py: Move CountStat.group_by into ZerverCountQuery.
Part of a larger refactoring to reduce cyclic dependencies between CountStat
and DataCollector (coming soon).
2017-04-14 11:41:07 -07:00
Rishi Gupta
341e1b54fc counts.py: Remove zerver_table from ZerverCountQuery.
Was only needed for filter_args, which are now gone.
2017-04-14 11:41:07 -07:00
Rishi Gupta
661de6bf25 counts.py: Remove filter_args argument from CountStat definition.
It turned out to not be that useful once we added subgroup. The previous
design of the CountStat object also assumed more reuseability of the *_query
strings than what ended up happening.

The filter_args also had some carrying costs:

* It's hard to be confident that filter_args other than the ones explicitly
  in our tests would have had expected behavior.
* The filter_args/join_args system is the most complex part of the CountStat
  object, and makes understanding the *_query strings unnecessarily
  difficult for a new contributor.
2017-04-14 11:41:07 -07:00
Rishi Gupta
4dfadba244 counts.py: Hardcode is_active=true in count_user_by_realm_query.
A step towards removing filter_args from the CountStat object.
2017-04-14 11:41:07 -07:00
Rishi Gupta
6bb97db136 analytics: Add active_users_audit:is_bot:day. 2017-04-14 11:41:07 -07:00
Rishi Gupta
cc75d83b74 counts.py: Reorder count_stats_ to put similar stats together. 2017-04-14 11:41:07 -07:00
Rishi Gupta
b396be4c98 models: Add index on RealmAuditLog.event_time.
Useful for the upcoming check_realmauditlog_by_user_query, if nothing else.

But I suspect it will indeed get use; looking for events around or within a
certain time is pretty natural for an audit log.

The main argument against I would say is that this should actually be a
joint index with something else. I'm not sure what that something else
should be, so just optimizing for what I think
check_realmauditlog_by_user_query will need for now.
2017-04-14 11:41:07 -07:00
Rishi Gupta
3d514c3e8d analytics: Add a default for the value column in assertTableState.
A default value of 1 is reasonable in this framework, especially for testing
things like LoggingCountStats.
2017-04-14 11:41:07 -07:00
Rishi Gupta
ce376261ca models: Add comment explaining RealmAuditLog.backfilled. 2017-04-14 11:41:07 -07:00
Rishi Gupta
2f74ccabf9 analytics: Add 15day_actives CountStat. 2017-04-14 11:41:07 -07:00
Rishi Gupta
9b661ca91f analytics: Replace CountStat.is_gauge with interval.
Groundwork for allowing stats like "Monthly Active Users".

CountStat.interval is no longer as clean a value as before, so removed it
from views.get_chart_data. It wasn't being used by the frontend anyway.

Removing interval from logger calls in counts.py is not a big loss since we
now include the frequency (which is typically also the interval) in
CountStat.property.
2017-04-14 11:41:07 -07:00
Rishi Gupta
d6c5c672d3 analytics: Add minutes_active CountStat. 2017-04-14 11:41:07 -07:00
Joshua Pan
6be482b0e7 Link /help/ documentation from in-app documentation.
Fixes: #4455.
2017-04-14 11:35:40 -07:00
Brock Whittaker
fe8f63c389 message view: Fix rare cases where click-to-reply was not handled.
The comment explains this change is fairly good detail.  This change
is designed to fix complaints that sometimes clicking on a message to
reply doesn't work, which we can reproduce as being caused by clicks
that happen simultaneous with a few pixels of mouse motion at the same
time as the click.

Comment and commit message rewritten by tabbott for clarity.
2017-04-14 11:25:15 -07:00
hackerkid
cd5334c827 Show local time of user in user_popover. 2017-04-14 10:38:29 -07:00
hackerkid
15cdd23525 Add option for setting timezone in user display settings. 2017-04-14 10:38:21 -07:00
hackerkid
bf3b2ac673 Include timezone in user_dict fields.
Tweaked by tabbott to avoid adding timezone to bot dicts, since bots
don't need a timezone.
2017-04-14 10:33:55 -07:00
hackerkid
2a0a84b229 Add moment.js third-party module via npm.
This is needed for timezone manipulations.  We may be able to replace
XDate with it in the future as well.
2017-04-14 10:22:06 -07:00
derAnfaenger
ecf9a50610 Clarify UI description of message retention. 2017-04-14 10:13:34 -07:00
Tim Abbott
a417fd3c0b MessageDictTest: Fix nondeterministic query counts.
This fixes an issue with a nondeterministic number of database queries
being used in fetching bulk messages from the database.  The source of
the problem was that we were fetching _all_ messages, not just the 600
that had been created by the test, and thus if the set of streams
present in messages in the test fixtures (which is random) changes,
the number of streams used (and thus number of queries) would change.
2017-04-14 09:55:27 -07:00
Tim Abbott
622b7f00f7 test_runner: Fix unnecessary sleep(1) in database teardown.
Apparently, Django's _destroy_test_db has a mostly unnecessary
sleep(1) before dropping the database, which obviously wastes a bunch
of time in the single-test runtime of their database teardown logic.

We work around this by monkey-patching that function to not do the sleep.
2017-04-14 09:30:47 -07:00
Umair Khan
a507a47778 testing: Use zulip_test_template for backend.
Instead of zulip_test, use zulip_test_template for backend DB. This
makes sure that the DB used by backend tests is different from the
DB, which will be zulip_test, used by Casper tests.
2017-04-14 10:23:31 +05:00
Umair Khan
bf713bcdfe testing: Don't create DB twice for backend.
In backend tests, only call generate-fixtures when --generate-fixtures
is explicitly passed or is_template_database_current() returns False.

We don't need to flush cache for backend tests because we bounce the key
prefix used to create cache keys before running every test
2017-04-14 10:23:16 +05:00
Steve Howell
e23b660ccc compose: Extract set_focus().
Most of the code here was in show_box(), but we also pull in the
call to get_focus_area() from compose.start().
2017-04-13 17:13:19 -07:00
Steve Howell
0841320966 compose: Extract maybe_scroll_up_selected_message().
The extraction here is straightforward, but where we put the
caller is a slightly subtle change.  Instead of continuing to
invoke this code at the end of show_box(), we instead call it
at the beginning of complete_starting_tasks().  This change is
valid, because show_box() and complete_starting_tasks() are only
ever called from compose.start().
2017-04-13 17:13:19 -07:00
Steve Howell
aa5409cf3a compose: Extract complete_starting_tasks(). 2017-04-13 17:13:19 -07:00
Steve Howell
e73b56c7b5 compose: Extract expand_compose_box(). 2017-04-13 17:13:19 -07:00
Steve Howell
79ff32a01e compose: Extract autosize_message_content(). 2017-04-13 17:13:19 -07:00
Umair Khan
519dcdb750 api_dev_fetch_api_key: Improve invalid email message.
Show a user friendly message to the user if email is invalid.
Currently we show a generic message:
"Your username or password is incorrect."
2017-04-13 12:48:13 -07:00
Umair Khan
80b019629c remote_user_sso: Improve invalid email message.
Show a user friendly message to the user if email is invalid.
Currently we show a generic message:
"Your username or password is incorrect."
2017-04-13 12:48:13 -07:00
Umair Khan
93aa478efb api_fetch_api_key: Improve invalid email message.
Show a user friendly message to the user if email is invalid.
Currently we show a generic message:
"Your username or password is incorrect."

The only backend which can accept a non-email username is LDAP.
So we check if it is enabled before showing the custom message.
2017-04-13 12:48:13 -07:00
Umair Khan
ad2114a7a8 validator.py: Create a validator for login email.
This validator raises JsonableError exception.

Fixes: #2748
2017-04-13 12:48:13 -07:00
Rishi Gupta
6e425814bf analytics: Add a few tests for fixtures.py.
The code in fixtures.py is only called from populate_analytics_db, and is
only used for generating pretty fixture data for manual testing. This commit
adds tests for a few things that were easy to add tests for, and provides
some minimal coverage of the file, but is not meant to be comprehensive.
2017-04-13 12:37:47 -07:00
Rishi Gupta
b555191ee7 analytics: Change subgroup and labels lists to dictionary in views.py.
A dict is more semantically appropriate than two lists with an assertion
that they be the same length.
2017-04-13 12:37:47 -07:00
Steve Howell
f06bd41586 Fix PM list sort ordering during scrollback situations.
Before this fix, if you scrolled back in your PM history for a
person that you've had recent conversations with, then we would
backdate the record of their most recent conversation, and this
would make the sort ordering under the "Private messages"
section incorrect.

This commit fixes this error by re-writing the function
message_store.insert_recent_private_message() to check any
prior timestamps for that user.  It also optimizes the function
a bit to short-circuit in O(1) time for cases where a recipient
already has a more recent timestamp, by having a Dict keyed
on user_ids_string.
2017-04-13 12:13:20 -07:00
Steve Howell
24461762da Add test_insert_recent_private_message(). 2017-04-13 12:13:20 -07:00
Steve Howell
f5550301cf Extract message_store.insert_recent_private_message().
This function is slightly easier to unit test, and it isolates us
from changing message formats.  This removes some extraneous
code that would ensure that message timestamps were >= 0 that
probaby dates back to some really old migrations.
2017-04-13 12:13:20 -07:00
Steve Howell
6b549248e8 Extract settings_filters.js. 2017-04-13 10:39:39 -07:00
Steve Howell
3e37f64f71 Extract settings_streams.js. 2017-04-13 10:39:39 -07:00
Steve Howell
70afb59cff Extract settings_users.js.
This affects three admin sections:

    * Users
    * Deactivated users
    * Bots
2017-04-13 10:39:39 -07:00
Steve Howell
0fc7b9907f Extract settings_org.js (and fix live updates).
This is mostly moving code, but we do add short-circuit logic
for some live-updating methods here.

Note that this affects two different sections of the admin app:

    * Organization settings
    * Authentication methods

We really want to move to one module per section, but there is some
legacy coupling that makes this difficult for now.
2017-04-13 10:39:39 -07:00
Steve Howell
a3b44148af Extract settings_emoji.js. 2017-04-13 10:39:39 -07:00
Steve Howell
76ec9cf60b Fix bug with (un)subscribe button showing on wrong narrow.
We had a bug for a while where if somebody subscribed you to a
stream, and you were narrowed to another stream, we'd show
a button in the "trailing bookend" to "Unsubscribe" from the
current stream.  I'm not sure how long we had that bug, but it
was at least a couple months old, and I couldn't track down an
issue for it.

Now we make sure that the stream event for the subscription is
related to the current narrow.

Users should still see messages when they subscribe/unsubscribe
themselves or when another user re-subscribes them to the stream
that they are narrowed to.
2017-04-13 08:01:44 -07:00
Steve Howell
33eb5ad237 Add narrow.is_for_stream_id() helper. 2017-04-13 07:49:55 -07:00
Brock Whittaker
ec956d6d6e integrations: Preserve scroll position on integration inspect.
This preserves the scrolltop state of the user when they enter into
an integration's specifics, so when they exit out it scrolls them
back down the page.

Fixes: #4424.
2017-04-12 21:14:21 -07:00
Tim Abbott
51233590a2 render_markdown_path: Remove unnecessary and broken caching.
The pages in question are already cached automatically by Zulip, and
the lru_cache decorator doesn't work, since `context` might contain
unhashable objects.
2017-04-12 20:29:04 -07:00
Tim Abbott
1747427bf3 upload: Fix URL for realm icons with S3 backend. 2017-04-12 19:48:24 -07:00
Tim Abbott
b6da9e86d4 test_templates: Fix ToS/Privacy templates. 2017-04-12 14:40:45 -07:00
Brock Whittaker
e3d510154d drafts: Move the draft empty placeholder logic to template render path.
This moves the logic to embed the translated string “(no topic)” to
only render in the handlebars template rather than saving in
localStorage and therefore being added to the message topic and
eventually put in the database if not changed.

Fixes: #4378.
2017-04-12 14:15:31 -07:00
K.Kanakhin
4891a8d850 Add default response for terms and privacy endpoints.
- Add setting for `privacy policy` template defining.
- Configure default templates for `privacy policy` and
  `terms of service` pages.
- Add route for privacy page.
- Remove condition for showing `privacy` and `terms` pages.
- Add `privacy_policy` setting to context processor.
- Add documentaion part for `privacy` and `terms` templates
  configuration.
- Add tests.

Fixes #3686.
2017-04-12 14:09:14 -07:00
K.Kanakhin
3d4020fd1c tests: Add AssertNotIn helper to the base test class. 2017-04-12 14:09:14 -07:00
Tim Abbott
179913fcf2 mypy: Annotate Realm.property_types properly. 2017-04-12 14:09:14 -07:00
Tim Abbott
4d42b910cb tests: Refactor test_events for realm properties.
This removes individual tests for realm properties and replaces them
with a generic do_set_realm_property_test function to test each
property in the Realm.property_types attribute.

Addresses part of #3854.
2017-04-12 13:33:10 -07:00
Sarah
bf4d33793f tests: Refactor test_realm to fix code duplication.
This replaces individual tests for realm properties with a generic
do_test_realm_update_api function to test each property in the
Realm.property_types attribute.

Addresses part of #3854.
2017-04-12 13:26:53 -07:00
Umair Khan
c9140dfa4c testing: Use a random database name when running backend tests.
This decreases risk of conflicts between running the backend and
casper test suites.

Part of #1977.
2017-04-12 13:17:40 -07:00
Umair Khan
65b96aab0c testing: Extract functions to create/destroy test databases. 2017-04-12 13:17:32 -07:00
Brock Whittaker
b6d285f1f4 integrations: Fixup inconsistent lozenge heights.
This normalizes images to all take up 100px even if they fall short
so that the text that is underneath will always be horizontally
aligned.
2017-04-12 13:10:41 -07:00
Rishi Gupta
f3fc9721f4 analytics: Match client names in populate_analytics_db to populate_db.
Originally, all the client names in populate_analytics_db started with
underscores to make it easy to selectively delete and regenerate them when
re-running populate_analytics_db.

We eventually want to merge populate_analytics_db into populate_db though,
in which case it makes more sense for them to share client names, and not
worry about the case where we run (or re-run) populate_analytics_db
independently of populate_db.
2017-04-12 11:45:15 -07:00
Adarsh S
d54dea819d Add option for re-running failed tests.
This adds the option '--rerun' to the `test-backend` infrastructure.
It runs the tests that failed during the last 'test-backend' run.  It
works by stailing failed test info at var/last_test_failure.json

Cleaned up by Umair Khan and Tim Abbott.
2017-04-12 11:35:31 -07:00
Tim Abbott
79ad174ad3 settings: logging configuration to consistently email errors.
This fixes 2 issues:
* Some exceptions were not being properly emailed to admins.

* A bug in the parens placement in the default Zulip handlers list
  resulted in the console/file handlers being accidentally excluded if
  !ERROR_REPORTING.

Fixes #4127.
2017-04-12 11:17:57 -07:00
Umair Khan
24295e6ac8 i18next: Add expirationTime option to cache.
This ensures that we don't fill up local storage with cached
translations data when using a server that restarts often (e.g. a
development environment).

Fixes: #4443.
2017-04-12 09:32:49 -07:00
Umair Khan
0cd7c400e1 i18next: Add i18next: to the local storage cache prefix.
This just makes it easier to see what these local storage entries are
related to.
2017-04-12 09:32:31 -07:00
Umair Khan
9dec5306ce makemessages.py: Handle unicode strings.
This commit applies to Python 2. It seems that sorted()
cannot handle non-ascii character unless the strings are
marked as Unicode.
2017-04-11 22:32:06 -07:00
Joshua Pan
b39006655e prod-requirements.md: Fix grammar.
Change "strong" to "strongly" (adverb).
2017-04-11 22:30:02 -07:00
Rishi Gupta
44502da767 tools: Add check for uncommitted files to PR review scripts. 2017-04-11 22:29:38 -07:00
Brock Whittaker
ffa654f780 left-sidebar: Remove <hr> divider if last pinned stream is unpinned.
The <hr> is supposed to separate the pinned streams from the unpinned
streams, so if the <hr> is the first element (checked by doing
$hr.prev().length === 0), then it means there are no longer any pinned
streams and therefore it isn’t necessary to have a divider.

Fixes: #4395.
2017-04-11 17:06:37 -07:00
Tomasz Kolek
2a55eff44b integrations: Add test event handler to Solano. 2017-04-11 16:59:06 -07:00
Brock Whittaker
d74f72f08f gear-menu: Re-add the organization settings link.
This re-adds the organization settings link and toggles the text
dependent on whether the user is an administrator or not.

Fixes: #4201.
2017-04-11 16:31:33 -07:00
Brock Whittaker
1f8d9a46f0 Remove extra "Unsubscribe" on left-sidebar stream popover.
An extra "Unsubscribe" was left over from when it was a CSS :pseudo
content rather than text in the templates.
2017-04-11 16:14:55 -07:00
Brock Whittaker
473214b32f stats: Change popover font size and weight to be more readable.
This changes the font size and weight of the popver at the bottom
of the screen (hover over "?" to see) to be a larger font size
(increased to 0.75rem from 11px) and to a bolder font weight
(500 from 300) which improves the readability of it.
2017-04-11 14:00:27 -07:00
Rishi Gupta
794c7c5508 user docs: Add info about max size for uploaded files. 2017-04-08 12:59:24 -07:00
Aditya Bansal
d56100693d profile-popover: Fix position to hide the pointed-to message border.
In this commit we just adjust the position of user profile popover
opened when we click upon buddy from buddy list to view user profile.
The new position ensures that the little blue border visible from back
due to pointed to message is completely hidden by the popover.
2017-04-07 17:34:57 -07:00
Aditya Bansal
5ff87892ee profile-popover: Fix extra padding in user-profile popovers.
In this commit we remove the extra padding appearing around the
user profile images. This can be only reproduced when opening
user profile from buddy list.
2017-04-07 17:34:57 -07:00
Abhijeet Kaur
8f88b045a4 Rename "Administration" to "Organization" in the settings UI.
This better sets expectatations for the fact that in Zulip, the
Organization settings UI is available read-only to non-administrator
users.

Tweaked by tabbott to update some additional references.
2017-04-07 17:32:56 -07:00
Joshua Pan
7ce200f8d7 Add documentation for Ctrl + [ hotkey. 2017-04-07 16:54:56 -07:00
rahuldeve
60803137f2 uploads: Add authorization check before serving files.
This is a remerge of e985b57259 (after
resolving merge conflicts, updating the tests, adding mypy annotations
etc.), which should now be correct, because we've done the necessary
database migration.

The rebase/remerge work was done by Tim Abbott and Aditya Bansal.

This is an important part of #320.
2017-04-07 16:35:28 -07:00
hollywoodno
401fae30f1 markdown: Render backend second level markdown.
By default, Python markdown tab length for indents is 4 spaces, which
require using 4 spaces or a tab to create nested elements. This
modifies that setting to specify 2-space indentation for nesting
elements only.

Modified significantly by tabbott to limit the change to just list
indentation.

Fixes #4252.
2017-04-07 16:14:57 -07:00
Umair Khan
5a3f83bba8 integrations: Move Trello webhook docs to markdown. 2017-04-07 15:52:15 -07:00
Umair Khan
21c129c93b integrations: Support writing docs in markdown.
Fixes #4011
2017-04-07 15:52:15 -07:00
Umair Khan
db81cd1c41 integrations: Create help_content property.
This property handles the rendering of help content.
2017-04-07 15:52:15 -07:00
Umair Khan
21f5c5cbf4 integrations: Pass context to integration objects. 2017-04-07 15:52:15 -07:00
Umair Khan
7ff699cd67 app_filters.py: Accept context in render_markdown_path. 2017-04-07 15:52:15 -07:00
Umair Khan
a45f8b463a app_filters.py: Use Django to load template.
This commit allows us to load template using Django in
render_markdown_path.
2017-04-07 15:52:15 -07:00
Steve Howell
06f9c28fd2 settings: Lazy-load settings sections.
For the settings UI, we now wait until a user goes to a particular
settings section before calling the appropriate function to set
up the section (which usually involves setting up click handlers
and populating initial data).
2017-04-07 15:20:12 -07:00
Steve Howell
c4b4979a74 Add Dict.clear() method. 2017-04-07 15:20:12 -07:00
Steve Howell
46af691e76 minor: Move line of code to hide digest settings.
This line was overlooked when extracting code to
settings_notifications.js.  It was not causing a user facing
error, but it was in the wrong place.
2017-04-07 15:20:12 -07:00
Steve Howell
7f17fc020f Extract settings_bots.js. 2017-04-07 15:20:12 -07:00
Steve Howell
153c24d071 Remove dead code related to bot/stream settings.
We had never-enabled code to allow users to set default
streams for their bots (for event registration, default sending, etc.).

This commit removes the code.
2017-04-07 15:20:12 -07:00
Abhijeet Kaur
015229fc68 Rename "Administration" to "Organization" in settings.
Rename "Administration" tab in Settings to "Organization."

Also rename the same in the navigation-bar for admin-users.
2017-04-07 07:18:50 -07:00
Aditya Bansal
17d32b959b scroll-bar: Fix perfect-scrollbar scrolling improperly in more topics.
In this commit we fix the issue of scrollbar occasionally scrolling
down too far when we click more topics option. Upon scrolling to top
the scroll gets reset everything returns to normal. This sometimes
leads to big blank space upon clicking more topics. This has been
fixed by reseting the scroll upon narrowing.
Fixes: #4440.
2017-04-07 07:11:17 -07:00
Tim Abbott
d540b2834d test_events: Fix errors with Python 2. 2017-04-06 19:26:42 -07:00
Tim Abbott
06a814f6d5 actions: Deduplicate backend display_settings code. 2017-04-06 15:33:41 -07:00
Tim Abbott
3a1912e829 mypy: Fix missing documentation_crawler annotation. 2017-04-06 15:33:41 -07:00
Tim Abbott
10e9c3bb84 documentation_crawler: Add exclude list.
This works around the issue that Google calendar returns errors on
HTTP HEAD requests.
2017-04-06 15:26:27 -07:00
Tim Abbott
b9c6c22b60 actions: Remove some unnecessary log_event calls.
Users editing messages or updating message flags are either already
recorded or not interesting from an audit perspective, and so there's
no need to use log_event with them.
2017-04-06 14:20:04 -07:00
Tim Abbott
6d27dcc801 actions: Remove log_message helper.
Since we are likely to never use the old populate_db history replay
logic, there's no point in having this extra code around.
2017-04-06 14:19:42 -07:00
Sumana Harihareswara
314843304d Add expectations for office hours and sprints. 2017-04-06 14:07:01 -07:00
Brock Whittaker
406c113ce1 integrations: Remove left-over integration instruction blocks.
In cases where a user goes from one hash to another in which
neither hash is "#", it will not properly clear the last instruction
block.

Fixes: #4407.
2017-04-06 13:49:54 -07:00
Steve Howell
262a4d5da6 Create topic_generator.js. 2017-04-06 12:23:44 -07:00
Brock Whittaker
3db61ecd20 settings-bots: Fix bots styling to prevent content from overflowing.
This fixes the styling of the container so that the text will not
overflow to the next line but instead will just wrap around the
container correctly.
2017-04-06 11:56:11 -07:00
Steve Howell
f37ce1eeb1 Extract settings_lab.js. 2017-04-06 11:28:36 -07:00
Steve Howell
89128a2272 Extract settings_muting.js. 2017-04-06 11:28:36 -07:00
Steve Howell
1f38884b27 Extract settings_notifications.js. 2017-04-06 11:28:36 -07:00
Steve Howell
fa143d4582 Extract settings_display.js 2017-04-06 11:28:36 -07:00
Steve Howell
47bdecdc4f Extract settings_account.js.
This code handles the settings pane for "Your account," which
has email/name/password/avatar/etc.
2017-04-06 11:28:36 -07:00
Tomasz Kolek
4867e68461 integrations: Add setup webhook message for Crashlytics.
This makes it easier to debug the setup process.
2017-04-06 11:27:48 -07:00
Aditya Bansal
9387fce024 loading-spinner: Fix improper display in upload avatar setting.
In this commit we fix the improper display of loading spinner in
upload avatar setting upon uploading new avatar repetitively one
after the other.
2017-04-06 09:06:14 +05:30
Aditya Bansal
aa10127cb6 loading-spinner: Fix position of spinner on home page.
In this we fix the positioning of the loading spinner on the home page
when its loaded for the first time. First time here does not mean first
time use but means first time of a new session.
2017-04-06 06:43:25 +05:30
Brock Whittaker
391a384c75 integrations: Clear float after #integration-instruction-block.
Clear the float after the instruction block so that the parent
container will respect the height of the child contents.

Fixes: #4425.
2017-04-05 17:31:05 -07:00
sinwar
4296d608ab test_server: Improve warning in venv check.
This (1) changes test_server to use the common `check_venv` method and
(2) improves check_venv to provide a clearer error message in the case
that you're inside Vagrant but not in a venv.

Tweaked by tabbott to borrow logic from run_dev.py.
2017-04-05 16:51:23 -07:00
sinwar
22b36ff2dc requirements: Upgrade python-twitter to latest version.
We no longer need a forked version, since our patches were merged into
master several months ago.

Fixes #3407.
2017-04-05 16:41:09 -07:00
Tomasz Kolek
a8633e0975 integrations doc: Move twitter doc to separate file. 2017-04-05 13:43:48 -07:00
Tomasz Kolek
1b6cdb92b7 integrations doc: Move trello-plugin doc to separate file. 2017-04-05 13:43:48 -07:00
Tomasz Kolek
85940aef7f integrations doc: Move trac doc to separate file. 2017-04-05 13:43:48 -07:00
Tomasz Kolek
d8ed13740d integrations doc: Move subversion doc to separate file. 2017-04-05 13:43:48 -07:00
Tomasz Kolek
68ca7e7fc5 integrations doc: Move rss doc to separate file. 2017-04-05 13:43:48 -07:00
Tomasz Kolek
65dfc97fc4 integrations doc: Move redmine doc to separate file. 2017-04-05 13:43:48 -07:00
Tomasz Kolek
06e4adc01d integrations doc: Move puppet doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
f4bd9dfda5 integrations doc: Move phabricator doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
4a6acc4fb9 integrations doc: Move perforce doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
5426725c43 integrations doc: Move openshift doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
484fef059b integrations doc: Move nagios doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
489a7d1784 integrations doc: Move mercurial doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
372c7224f0 integrations doc: Move jira-plugin doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
f0ace02e6c integrations doc: Move jenkins doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
34500f755c integrations doc: Move hubot doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
bd1103373d integrations doc: Move google-calendar doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
6ff130b829 integrations doc: Move git doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
d1b4a4546d integrations doc: Move email doc to separate file. 2017-04-05 13:43:47 -07:00
Tomasz Kolek
3c0287cfc7 integrations doc: Move codebase doc to separate file. 2017-04-05 13:37:37 -07:00
Tomasz Kolek
cbe00e020c integrations doc: Move capistrano doc to separate file. 2017-04-05 13:37:37 -07:00
Tomasz Kolek
a39c55b4ab integrations doc: Move asana doc to separate file. 2017-04-05 13:19:58 -07:00
Tomasz Kolek
5b17622589 docs: Move integrations.html to integrations/index.html.
Add omiting rule for all of integrations docs in test_templates.
2017-04-05 13:19:58 -07:00
Tomasz Kolek
62603940a7 integrations doc: Remove basecamp old-style doc. 2017-04-05 13:19:58 -07:00
Tomasz Kolek
fe55542078 integrations doc: Add footer about logos to all integrations.
Fixes: #4293
2017-04-05 13:19:58 -07:00
Tim Abbott
cfe8871dfc test_audit_log: Put all tests in a single test class.
This simplifies the process for adding new tests here a bit.
2017-04-05 12:53:59 -07:00
Maxim Averin
02900ff54a Switch do_change_bot_owner to use RealmAuditLog.
This requires adding an `acting_user` parameter to the
`do_change_bot_owner` function.
2017-04-05 12:50:55 -07:00
Tim Abbott
97af418be2 subs: Fix going down from 'Filter streams'.
The correct behavior here should be selecting the very first row.
2017-04-05 12:30:36 -07:00
Raghav Jajodia
40018f29fc create_stream: Disable up/down arrow keys when creating new streams.
Prevent switching of stream rows on pressing arrow key when focussed
on the 'Create stream' section (this would cancel the curren stream
creation flow).
2017-04-05 12:30:36 -07:00
digi0ps
a935325420 settings: Fix positioning of user upload spinner.
Previously the "Uploading" text was floating outside the upload
widget.

Fixes #4223.
2017-04-05 12:22:15 -07:00
Umair Khan
be65125d3d Handle unicode characters in email mirror.
Fixes #2328.
2017-04-05 12:18:41 -07:00
Aditya Bansal
a9cb193b51 docs: Update icon instructions to use the new font awesome CSS classes.
We basically want readers to use the new fa class as the base class
instead of icon-vector while using icons from font-awesome library.
2017-04-05 12:05:08 -07:00
Steve Howell
6b4825a763 tools: Convert test-js-with-node to Python.
This is mostly a straight port from bash to Python, but we
rename the coverage option to `--coverage` and we add checks
for being in a venv and being correctly provisioned.

Fixes #4009.
2017-04-05 12:02:49 -07:00
Tim Abbott
bfe512335b hotkey: Clean up state more consistently in node tests. 2017-04-05 11:59:48 -07:00
Steve Howell
e2a21303eb hotkeys: Simplify up/down handling for stream settings.
We've had this kind of hacky setting called message_view_only for
a long time in the hotkeys code, and it originally helped optimize
the code a bit.  It wasn't well maintained, and people started
adding non-message-view behavior to the arrow keys without flipping
that flag to false.  This change finally flips the flag to false,
which simplifies some of our logic.
2017-04-05 11:53:52 -07:00
Steve Howell
4a3211d6af hotkeys: Clean up dispatching of drafts hotkeys.
We now explicitly return true from process_hotkey() when we
handle up/down/backspace for the drafts modal.  Also, we no longer
call preventDefault() from drafts.draft_handle_events(), since the
caller does that, and we no longer return `true`, since we were
never inspecting the return value anyway.
2017-04-05 11:53:52 -07:00
Steve Howell
2ef9957cbc hotkeys: Handle up/down arrows in settings page.
The up/down arrows now navigate the left pane of the settings menu.
The code here was originally implemented as part of our settings
redesign, but the code was added in a place that became unreachable
after we fixed a bug with home_tab_obscured().  This commit
resurrects the code and places the guts of it in settings.js.  It
is possible that we want to clean this code up eventually to deal
better with hidden blocks.
2017-04-05 11:53:52 -07:00
Steve Howell
4bbd73a9a2 Extract list_util.js for navigating lists.
The code here used to live in hotkey.js.  Its complicated calling
protocol made it difficult to unit test.  We are also trying to
slim down hotkey.js.

Our arrow navigation for things like `#stream_filters` has always
been kind of awkward, since it's difficult to get the focus to
their list items.  This commit does nothing to fix that yet.
2017-04-05 11:53:52 -07:00
Cynthia Lin
59bfd4e1c7 integrations: Update logos.
Fixes #3219
2017-04-05 11:45:51 -07:00
Umair Khan
846e8686c4 makemessages: Exclude hidden files.
Fixes #3981.
2017-04-05 11:09:32 -07:00
Brock Whittaker
bccda3c76a Change subscriber data source to come from in-memory.
The subscriber data is currently pulled from the web needlessly
when it exists in memory. This processes data returned from
the `stream_data.get_sub_by_id(n).subscribers` and the
`people.get_person_from_user_id(n).email` methods to build the
same list of subscribers that is sent from the server.

Fixes: #4314.
2017-04-04 18:26:17 -07:00
Rohitt Vashishtha
f27b0231f1 api-docs: Fix JavaScript code sample. 2017-04-04 18:16:19 -07:00
Brock Whittaker
35bb02ead6 Fix incorrect content height on settings overlay.
This fixes the height of the content body to be 100% - 45px instead
of 100% - 60px which is a fix necessary due to the previous change
in height of the settings navbar.
2017-04-04 18:14:54 -07:00
Brock Whittaker
904611cfef Add overflow: hidden to .content-wrapper to prevent sidebar flash.
This prevents the non-deterministic flash of the sidebar outside
of the overlay in some browsers.
2017-04-04 18:14:54 -07:00
Umair Khan
c1049f5bd9 github: Warn if GitHub settings are not filled. 2017-04-04 18:03:33 -07:00
Umair Khan
8e87ba439d github: Go to registration if email is invalid. 2017-04-04 18:03:33 -07:00
Umair Khan
c5218fb584 github: Pass proper parameters to authenticate.
Django tries to authenticate against all backends one by one.
The authenticate() function of GitHub backend used to take
*args and **kwargs arguments due to which it could be called
against any set of arguments. Django uses arguments to
differentiate authenticate() methods.
2017-04-04 18:03:33 -07:00
Umair Khan
3bac73159a backends: Test authenticate() with kwargs.
Django uses arguments to differentiate between different authenticate
 function so it is important to pass arguments in a predictable manner.
 Keyword args will test the name of the argument as well.
2017-04-04 18:03:33 -07:00
Umair Khan
8c3a0126c1 test_auth_backends.py: Add get_username(). 2017-04-04 18:03:33 -07:00
Brock Whittaker
5501dafd2f settings: Fix avatar settings 'float' property.
This fixes the float of the avatar box so it does not visually
extend past the .settings-section container.
2017-04-04 17:53:40 -07:00
Raghav Jajodia
4b0ca4c852 streams: Restore stream name in 'Create streams'.
On filling out the name and description for new stream,
and changing the tab (e.g. by clicking on a stream on the left),
then come back to 'Create streams', it should restore stream name
similar to the stream description.

Fix #4311.
2017-04-04 17:17:20 -07:00
Umair Khan
07ea08c184 test_classes: Remove assert_max_length.
We should avoid this kind of assertions because they are
not deterministic.
2017-04-04 17:07:34 -07:00
Umair Khan
24dfc49792 test_users: Change assert_max_length to assert_length. 2017-04-04 17:07:34 -07:00
Umair Khan
5682b208ea test_signup: Change assert_max_length to assert_length. 2017-04-04 17:07:34 -07:00
Umair Khan
1b8d9f186e test_presence: Change assert_max_length to assert_length. 2017-04-04 17:07:34 -07:00
Umair Khan
cc96cefe75 test_messages: Change assert_max_length to assert_length. 2017-04-04 17:07:06 -07:00
Steve Howell
ec59b0d9eb admin screens: Change "Never" to "Unknown" for last activity.
Admins might not know whether users have "never" had activity;
more likely it's just been a long time.
2017-04-04 15:57:10 -07:00
Steve Howell
205f2c1562 Add ping_only flag for presence updates.
The web app doesn't need any presence data for its first ping to
the server, because it already has up-to-date presence info in
page_params.  So now we can tell the server not to send us a big
payload that we were already ignoring.
2017-04-04 15:57:10 -07:00
Steve Howell
3a332aee0b Exclude dormant users from buddy list queries.
If a user has not shown activity in two weeks, we exclude
them from the buddy list.  This should help performance for
large realms and mobile clients.
2017-04-04 15:57:10 -07:00
Steve Howell
2420df8415 buddy list: Make small realms show all users.
For small-ish realms (<= 250 users), we ensure that the presence
info includes all realm users the front end knows about, even in
cases where the server sends down a slimmed version of presence
data.  We make the users "offline" by default, of course.

This commit sets us up to optimize larger realms without concerns
of breaking small realms.  Small realms may want to continue to
show all users, even users who may have been offline several weeks,
since it doesn't clutter their API as much as it would for big
realms.
2017-04-04 15:57:10 -07:00
Steve Howell
a4d5a12ca0 Add people.get_realm_count(). 2017-04-04 15:57:10 -07:00
Steve Howell
2718bd0b5d Extract presence.js to track presence info.
Most of this code was simply moved from activity.js with some
minor renaming of functions like set_presence_info -> set_info.

Some functions were slightly nontrivial extractions:

    is_not_offline:
        came from activity.huddle_fraction_present

    get_status/get_mobile:
        simple getters

    set_user_status:
        partial extraction from activity.set_user_status

    last_active_date:
        pulled out of admin.js code

We also fixed activity.filter_and_sort to take user_ids.
2017-04-04 15:57:10 -07:00
Harshit Bansal
0605a9fb0f templates: Rename admin-alias-list.handlebars.
Rename `admin-alias-list.handlebars` to
`admin-realm-domains-list.handlebars`.

Fixes: #3145.
2017-04-04 15:48:03 -07:00
Harshit Bansal
885ec07192 frontend: realm_alias to realm_domain migration.
* Change the classes and ids of different widgets and modals
and make suitable changes in `admin.js`.

* Remove any other occurrences of `alias` or `realm_alias`
from admin.js.
2017-04-04 15:48:03 -07:00
Harshit Bansal
cebcfb8d29 test_realm_aliases.py: realm_alias to realm_domain migration.
* Remove any occurrences of `alias` or `realm_alias`.

* Rename `test_realm_aliases.py` to `test_realm_domains.py`.
2017-04-04 15:48:03 -07:00
Harshit Bansal
b40a8ea20b views/realm_aliases.py: realm_alias migration.
* Rename `views/realm_aliases.py` to `views/realm_domains.py`.

* Remove any occurrences of `alias`.
2017-04-04 15:48:03 -07:00
Harshit Bansal
664b23c495 commands: Rename realm_alias command to realm_domain. 2017-04-04 15:48:03 -07:00
Harshit Bansal
362ee482c0 commands/realm_alias.py: Remove any occurrences of alias. 2017-04-04 15:48:03 -07:00
Harshit Bansal
fe4cba9aa7 test_events.py: Remove any remaining occurrences of alias. 2017-04-04 15:48:03 -07:00
Harshit Bansal
711a3f8037 actions.py: Rename remaining occurrences of alias' to realm_domain`. 2017-04-04 15:48:03 -07:00
Harshit Bansal
c226c651f7 actions.py: Rename do_remove_realm_alias() to do_remove_realm_domain(). 2017-04-04 15:48:03 -07:00
Harshit Bansal
a08155b09e actions.py: Rename do_change_realm_alias() to do_change_realm_domain(). 2017-04-04 15:48:03 -07:00
Harshit Bansal
2da4fc0dc4 actions.py: Rename do_add_realm_alias() to do_add_realm_domain(). 2017-04-04 15:48:03 -07:00
Harshit Bansal
983225612d actions.py: Rename get_realm_aliases() to get_realm_domains(). 2017-04-04 15:48:03 -07:00
Harshit Bansal
582d8a351f zerver/models.py: Rename remaining occurences of alias to realm_domain. 2017-04-04 15:48:03 -07:00
Harshit Bansal
92c512d679 zerver/models.py: Rename can_add_alias() to can_add_realm_domain(). 2017-04-04 15:48:03 -07:00
Harshit Bansal
6f0b46d84f create_realm.py: Remove unnecessary imports. 2017-04-04 15:48:03 -07:00
Harshit Bansal
ac2172e233 models: Rename RealmAlias model to RealmDomain.
Includes a migration.
2017-04-04 15:48:03 -07:00
Kouhei Sutou
7c43aa1372 message: Use pgroonga.match_positions_character.
We can remove byte version text highlight method with this change.

pgroonga.match_positions_character was added in PGroonga 1.1.1:
http://pgroonga.github.io/reference/functions/pgroonga-match-positions-character.html

PGroonga 1.1.1 was released at 2016-08-31. So we can use it.
2017-04-04 14:05:45 -07:00
Eeshan Garg
da599ad28c webhooks/gitlab: Add support for filtering GitLab branches. 2017-04-04 13:51:08 -07:00
Maxim Averin
08690132fe Decrease maximum number of search suggestions.
This fixes an issue with the menu going below the bottom of screen
with non-tiny windows, and it was rare that anyone benefitted from the
extra suggestions.

Fixes: #4133.
2017-04-04 13:02:10 -07:00
Brock Whittaker
51f68fce79 Remove overflow: hidden constraint on .settings-section.
This `overflow: hidden` constraint would make it so that modals
embedded in the sections would have their edges cut off. This fixes
that and doesn’t seem to cause any other regressions.

Fixes #4208.
2017-04-04 12:18:18 -07:00
Steve Howell
3f4301bcec node tests: Simplify i18n.js and avoid jquery leak.
We remove the jquery dependency here and just search for strings
in the text.  It turns out the test was leaking jquery into
message_edit, so now we explicitly stub jquery in message_edit.
2017-04-04 06:51:31 -07:00
Steve Howell
e4e0b6d572 node tests: Speed up echo.js by stubbing window. 2017-04-04 06:31:37 -07:00
Steve Howell
fa729f11bd node tests: Speed up activity.js by stubbing jquery. 2017-04-04 06:31:37 -07:00
Kamal Marhubi
8d787ed887 style: Increase messagebox inter-paragraph spacing
The default is too tight for easily distinguishing paragraphs. This
change increases it slightly, while keeping the last paragraph's
margin at the original value.
2017-04-03 17:28:42 -07:00
Yago González
8f8efb4664 frontend: Show KaTeX errors not related to syntax. 2017-04-03 17:01:50 -07:00
Yago González
c1fea74a65 markdown: Load KaTeX in the app. 2017-04-03 17:01:50 -07:00
Steve Howell
79e945edb1 node tests: Test people.small_avatar_url(). 2017-04-03 16:34:16 -07:00
Steve Howell
e21bb2ebfe node tests: Test people.pm_reply_to(). 2017-04-03 16:34:16 -07:00
Steve Howell
4da74b3cde Remove duplicate copy of get_full_name(). 2017-04-03 16:34:16 -07:00
Steve Howell
7d3a7e12e8 node test: Add test_get_recipients(). 2017-04-03 16:34:16 -07:00
Steve Howell
4ec4b28562 Add tests for people.reply_to_to_user_ids_string(). 2017-04-03 16:34:16 -07:00
Steve Howell
99d603b424 node tests: Add test cases for pm-with filter.
This commit gets us to 100% line coverage for filter.js.
2017-04-03 16:31:57 -07:00
Steve Howell
3ddb8690af node tests: Test some zero-count cases for unread.js.
Our unread.js code basically silently treats empty recipient
strings or unknown streams as having zero unread messages,
which is probably the correct behavior.  We now have tests
that cover this.  This commit also gets us to 100% line
coverage on the module (but not yet 100% branch coverage).
2017-04-03 16:31:57 -07:00
Steve Howell
8d647868ca Use fewer messages in test_num_unread_for_subject().
I am not sure why I originally coded this to use 10000
messages, since it's not really a performance test.
2017-04-03 16:31:57 -07:00
Tim Abbott
943a3b1cff alerts: Fix "Try Now" retry get_events button.
This has apparently been broken since we renamed get_updates to
get_events.
2017-04-03 16:22:05 -07:00
Brock Whittaker
34f9ccb87c alerts: Change sidebar alerts to be at top of the screen.
This changes the alerts to be individual boxes that slide down from
the top of the screen for a better UI experience.
2017-04-03 16:22:05 -07:00
Steve Howell
2d52463b61 Extract ui_report.js.
This moves the implementations of error/report/message from
ui.js to ui_report.js.  They had been shimmed before, so calling
modules still use the same names to call the functions, but we
no longer need the shims.
2017-04-03 07:13:25 -07:00
Luis Saul Trinidad
d8fad9587c code-style.md: Fix typo for selected_related().
This changes a mention to QuerySet's method `.select_related()` which was written as `.selected_related()`.
2017-04-03 06:43:19 -07:00
Brock Whittaker
28a63da02f Fix the grid labels to have a min-width of 200px.
The labels should respect their original width of 200px but overflow
if the language or content is too long.
2017-04-02 14:36:26 -07:00
Steve Howell
3d1ce3fafe js deps: Approve some more deps to break. 2017-03-30 15:35:57 -07:00
Brock Whittaker
5546f037a7 admin: Remove 200px width limitation on .grid label.
This removes the 200px width limitation that was part of a previous
style guide for the settings/administration pages. It force-wraps
lines that shouldn't be wrapped and no longer serves its original
purpose.

Fixes: #4312.
2017-03-30 13:30:45 -07:00
Sampriti Panda
32e76c2c60 drafts: Move snapshot_message from compose to drafts
Previously drafts called compose.snapshot_message which would then
get the message object from compose.create_message_object. This method often
checked for the validity of stream/user recipients which would often cause tracebacks.

The new method in drafts.snapshot message just gets the data from the fields and
stores them in the draft model without any additional checking.
2017-03-30 10:20:37 -07:00
Sampriti Panda
400a2e0ff1 drafts: Fix faulty draft_model addDraft and editDraft tests
The addDraft and editDraft tests were copying objects by reference
which meant the methods weren't tested properly. Due to this, a bug with
stubTimestamp was also discovered where the method wasn't getting stubbed
2017-03-30 10:20:37 -07:00
Rohitt Vashishtha
4659f97649 sidebar: Make icon clickable for '< All Streams' in left sidebar. 2017-03-30 10:12:19 -07:00
Umair Khan
4f9b6303a7 test_narrow.py: Add workaround for Pgroonga regression.
Due to Pgroonga regression, there is a difference in search
result between Travis and development env due to which one of
our tests fails. This commit makes sure that the test passes
for both strings till the Pgroonga bug is resolved.
2017-03-29 22:12:15 -07:00
Rohitt Vashishtha
c7b40e76ac css: Make thirdparty-fonts.css load before Zulip stylesheets. 2017-03-29 21:18:43 -07:00
Sarah
dea563b27e zerver/lib/test_events: Refactor realm update tests.
Created do_set_realm_property_test and refactored individual realm tests
to use this function for testing updating realm properties.
2017-03-30 02:17:10 +00:00
Rishi Gupta
754b547e88 populate_db: Change enter_sends to True for development users.
Fixes #4355.
2017-03-29 18:38:30 -07:00
Tim Abbott
9aa77e491e tests: Get hotspots to 100% test coverage. 2017-03-29 14:04:33 -07:00
Rishi Gupta
c65f9c1510 docs: Update reference to font awesome version in user-docs. 2017-03-29 11:36:51 -07:00
Rishi Gupta
daed1fc2aa user_info_popover_content: Fix padding issues.
Removes 1px padding around edge of avatar added by bootstrap.
Removes column of whitespace to right of avatar.
2017-03-29 11:36:51 -07:00
Rishi Gupta
07592a6692 user_info_popover_content: Change wording to match search autocomplete.
The new wording is also more active, and shorter.
2017-03-29 11:36:51 -07:00
Rishi Gupta
4063ab6cf7 user_info_popover_content: Reorder actions into sections. 2017-03-29 11:36:51 -07:00
Amy Liu
6f061beb46 hotspots: Add backend support for tutorial hotspots.
This commit adds the backend support for a new style of tutorial which
allows for highlighting of multiple areas of the page with hotspots that
disappear when clicked by the user.
2017-03-29 11:34:32 -07:00
Umair Khan
33c130a603 Make pgroonga tests pass to workaround pgroonga regression.
Note that the old behavior was correct; we're just merging this to
make the tests pass until upstream can fix it.
2017-03-29 11:32:37 -07:00
Tim Abbott
9a9f0f86e9 test_messages: Fix sometimes incomplete coverage in StarTests.
This test had nondeterministically incomplete test coverage.
2017-03-28 11:41:45 -07:00
JPJPJPOPOP
f7d2889c1d drafts.js: Prevent delete from triggering in the back of draft overlay.
Fixes #4340.
2017-03-27 18:13:57 -07:00
Rishi Gupta
8617c2d594 populate_db: Make Iago staff.
Will make it easier to test the /activity page.
2017-03-27 16:43:35 -07:00
Yago González
0b87118b03 docs: Add explanation on small fixes in PRs. 2017-03-27 14:44:33 -07:00
Yago González
2f5addc174 i18n: Add missed strings. 2017-03-27 14:30:28 -07:00
Yago González
58880b6695 frontend: Remove unnecessary punctuation. 2017-03-27 14:30:28 -07:00
Brock Whittaker
45a5932236 Merge ./static/images/landing-page/assets into parent folder.
There appears to be an issue in which on production the
./landing-page/assets folder is excluded from the build process,
so move it to the parent folder to fix the assets to appear in
production.
2017-03-27 14:08:45 -07:00
Jonathan Pan
5556d2341c hotkey.js: Add hotkey for drafts.
* 'd' in message view opens drafts.

This also adds hotkeys within the drafts UI:
* Up/down arrow keys navigate the drafts.
* Pressing enter edits the selected draft.
* Pressing backspace deletes the selected draft.

Some variable names tweaked by tabbott.
2017-03-27 14:05:00 -07:00
Harshit Bansal
d17b759fa2 admin: Display last active time of users in admin users table.
Fixes: #2097.
2017-03-27 13:39:47 -07:00
Tim Abbott
d565990c68 reload: catch exceptions trying to preserve state. 2017-03-27 13:36:31 -07:00
Tim Abbott
2eacc7317d reload: Remove cleanup_before_reload logic.
Zulip's logic for garbage-collecting data structures before reloading
was a fix for a Chrome memory leak that lasted across reloads a few
years ago.  That memory leak is probably now fixed, and thus logic is
causing lots of JavaScript tracebacks that are probably not useful.

So, let's try removing this cleanup logic (everything but the
still-useful deletion of the event queue).
2017-03-27 13:23:10 -07:00
Tim Abbott
5776ecfac2 test_audit_log: Fix unnecessary user creation. 2017-03-27 13:23:10 -07:00
Maxim Averin
f213369e1d zerver: Replace log_event with RealmAuditLog in do_change_avatar_fields. 2017-03-27 13:23:10 -07:00
Tim Abbott
141469399b RealmAuditLog: Add an extra_data field.
This will be useful for logging any additional details that we might
want to display.
2017-03-27 13:22:58 -07:00
Steve Howell
24ee369d43 Improve error message in message_list.select_id(). 2017-03-27 10:26:30 -07:00
Steve Howell
6314f60edc Keep compose open if left arrow does not cause message edit.
If somebody hits the left arrow to edit a message, but there are
no messages available to edit, then leave them in the compose box.
2017-03-27 10:15:05 -07:00
Steve Howell
293c89ba94 message edit: Only enable left-arrow-editing for content.
We no longer let the left arrow put you into the message edit
UI for a message where you can only edit topics, since that is
just confusing to most users.

This change also improves error handling a bit, and it removes
an unnecessary call to rows.id().

Finally, it moves some logic out of message_list.js, so that we
don't have a circular dependency for this codepath.

Fixes #4259
2017-03-27 10:02:19 -07:00
Steve Howell
c0a6038a95 css: Enforce one selector per line.
While it's sometimes nice to put a few selectors on the same line,
it is generally better to have a consistent way of formatting our
selectors, and most of our code up until now lists them vertically.
This change fixes the linter to enforce one selector per line, and
it cleans up the places in the CSS where we had multiple selectors
on the same line.

The advantages of one-per-line are as followers:
    * cleaner diffs
    * easier to see when multiple areas of the app may have the
      same format
    * less likely to go over 80 cols
    * makes it more clear where we have deep nesting in the
      individual selectors
    * makes it easier for our linting tools to enforce
      whitespace violations

This also fixed an old bug where we had ".landing_page h2, h4", which
sets "h4" styles outside of the landing page.
2017-03-26 16:57:33 -07:00
Steve Howell
3d76088f59 tools: Make CSS style more consistent with opening brace.
We now always put the opening brace of a CSS section on
the same line as the last selector (with a space in front).
2017-03-26 16:57:33 -07:00
Eeshan Garg
8933b5b31d github_webhook: Filter specific GitHub branches.
Fixes: #4000
2017-03-26 13:32:24 -07:00
Tim Abbott
db92dec05e test_events: Start using test_dict_only.
This is a proof of concept; we'll want to migrate the rest of the call
points soon.
2017-03-26 13:10:54 -07:00
Tim Abbott
2160088d94 test_events: Enforce length of events list. 2017-03-26 13:10:54 -07:00
Tim Abbott
118f2db22d validators: Add a test_dict_only validator that bans other arguments.
This is primarily intended to be useful in EventsRegisterTest.
2017-03-26 13:10:54 -07:00
Tim Abbott
b5cf0067d5 logging_handlers: Avoid super long subject lines. 2017-03-26 13:10:43 -07:00
Tim Abbott
36bb2bf54a AdminZulipHandler: Bring logging_handlers.py to 100% test coverage.
This involved fixing some unupdated code in one code path.
2017-03-26 13:10:43 -07:00
Tim Abbott
267346f5fb AdminZulipHandler: Support passing a record without a request. 2017-03-26 13:10:43 -07:00
Tim Abbott
efa151b488 AdminZulipHandler: Extract add_request_metadata. 2017-03-26 13:10:43 -07:00
Tim Abbott
4276face7f AdminZulipHandler: Construct report more dynamically. 2017-03-26 13:10:43 -07:00
Tim Abbott
1a17b11788 logging_handlers: Add tests for main error reporting code path. 2017-03-26 13:10:43 -07:00
Tim Abbott
033fd98e5f decorator: Add rate limiting to zulip_login_required. 2017-03-26 13:10:43 -07:00
Tim Abbott
385551ff62 decorator: Add rate-limiting to JSON views. 2017-03-26 13:10:43 -07:00
Tim Abbott
6c4c8178f0 zulip_login_required: Set request._query.
This fixes an exception we had in the user_activity queue processor
when changing email addresses, since the URL containing the
confirmation key was longer than 50 characters.
2017-03-26 13:10:43 -07:00
Steve Howell
cf6545a71f reactions: Only warn for unknown user ids.
If we get reactions for deactivated users, or otherwise missing
users, we only issue a blueslip warning now.  The function
get_message_reactions() was indirectly causing blueslip errors
before this fix, but we can downgrade to warnings now that this
function has better unit tests around it.

We eventually want to track deactivated users on the client.

Fixes #4289
2017-03-26 11:51:36 -07:00
Steve Howell
3da047e10e Add people.is_known_user_id(). 2017-03-26 11:39:06 -07:00
Steve Howell
80addd902c Extract local vars in get_message_reactions(). 2017-03-26 11:39:05 -07:00
Steve Howell
03b7e59b59 node tests: Add reactions.js test module.
We test get_message_reactions() in our first test here.
2017-03-26 11:39:05 -07:00
Feorlen
10ccfcdc8e Set umask 022 before starting prod install.
Fixes #2372.
2017-03-25 23:59:44 -07:00
Tim Abbott
5672618b82 css: Extract popovers.css. 2017-03-25 20:14:17 -07:00
Bao Chau
9b6e648acb registration: Fetch length limits from the backend's actual sizes.
This makes these more likely to remain accurate over time.

Fixes #4211.
2017-03-25 20:10:12 -07:00
Rishi Gupta
30024d0a8f models: Remove Realm.domain. 2017-03-25 19:55:48 -07:00
Rishi Gupta
b416587aab Change sender_domain to sender_realm_str in message dict. 2017-03-25 19:50:24 -07:00
Rishi Gupta
88abb7871d Remove domain from list of pre-fetched fields for message recipients. 2017-03-25 19:50:24 -07:00
Tim Abbott
5bf01fb7d4 create-production-venv: Fix issues with api/ relative path.
Fixes #4313.
2017-03-25 19:49:26 -07:00
Tim Abbott
c7f1a7aa19 test_script: Use LooseVersion for version conparisons.
Fixes #4292.
2017-03-25 19:49:03 -07:00
Cynthia Lin
f41883ce8d subs.js: Refactor row data functions to return objects. 2017-03-25 18:35:21 -07:00
Cynthia Lin
6e2d180a34 hotkeys: Add hotkey n for opening New streams modal in Streams menu. 2017-03-25 18:35:21 -07:00
Cynthia Lin
ca460fad1f hotkeys: Add hotkey V for viewing selected stream in Streams menu. 2017-03-25 18:35:21 -07:00
Cynthia Lin
a027e9318d hotkeys: Move cursor to Filter streams input if at top of Streams menu.
Fixes #4227
2017-03-25 18:35:21 -07:00
Cynthia Lin
b800cb05c0 hotkeys: Add left/right arrow keys to toggle views in Streams menu.
Fixes #4228
2017-03-25 18:35:21 -07:00
Cynthia Lin
fb89d8a2bf subs.js: Refactor modal row functions. 2017-03-25 18:35:21 -07:00
Cynthia Lin
69c32daffa hotkeys: Add U hotkey for unsubscribing/subscribing in Streams menu.
Fixes #4229
2017-03-25 18:35:21 -07:00
Cynthia Lin
d17131dcb4 hotkeys: Rename subs.arrow_keys() to subs.switch_rows(). 2017-03-25 18:35:21 -07:00
Aditya Bansal
42265fe035 Fix '@' in userprofile popover to use font-awesome icon. 2017-03-25 18:30:58 -07:00
Aditya Bansal
91962aa6ab font-awesome: Fix font-awesome 4.7.0 upgrade in a hacky way.
What actually has been done below is to just copy the css class defination
from the latest font-awesome css to be here and since the rest of the stuff
in /third/fontawesome was updated in ee0b16b1ef
we should be able to use this safely until we update all font-awesome class
usage in templates.

Fixes #4302.
2017-03-25 18:30:40 -07:00
Harshit Bansal
11327fda7c actions.py: Only admins and bot's owner should recieve bot related events.
Modify `bot_owner_user_ids()` to return the user_ids of only
admins and bot owners instead of all the current active users.
This was causing a traceback on the frontend.

Fixes: #3391.
2017-03-25 18:22:15 -07:00
Elliott Jin
98ddb4453e test-backend: Raise zerver/views/home.py test coverage to 100%. 2017-03-25 18:16:16 -07:00
Elliott Jin
1c0d58f897 test-backend: Raise zerver/views/auth.py test coverage to 100%. 2017-03-25 18:16:16 -07:00
K.Kanakhin
fe3213798d retention: Add models to store expired messages.
This addresses part of #106.
2017-03-25 18:12:06 -07:00
Tim Abbott
18e66983c4 signals: Fix mypy error. 2017-03-25 18:06:04 -07:00
K.Kanakhin
234a1f8e61 retention-period: Add retention period to front-end admin organization settings.
- Add message retention period field to organization settings form.
- Add css for retention period field.
- Add convertor to not negative int or to None.
- Add retention period setting processing to back-end.
- Fix tests.

Modified by tabbott to hide the setting, since it doesn't work yet.
The goal of merging this setting code now is to avoid unnecessary
merge conflicts in the future.

Part of #106.
2017-03-25 17:57:18 -07:00
Tim Abbott
6a884acff5 signals: Avoid importing bugdown from early initialization.
This fixes `tools/build-release-tarballs` failing.
2017-03-25 17:27:46 -07:00
Tim Abbott
004133561b realm_filters: Support ? in URL format strings. 2017-03-25 17:13:34 -07:00
Tim Abbott
22d284950d trello: Clean up the documentation. 2017-03-25 17:04:52 -07:00
hollywoodno
75d9630258 Add notifications on new logins to Zulip.
This adds helpful email notifications for users who just logged into a
Zulip server, as a security protection against accounts being hacked.

Text tweaked by tabbott.

Fixes #2182.
2017-03-25 16:50:52 -07:00
Rishi Gupta
9f60dd8387 analytics: Send zeros for data.user.bot in Messages Sent Over Time.
It will simplify the logic needed to process the "Sent by Me" view in
Messages Sent Over Time in stats.js.

Also, we gzip the data sent from our server, so there is little additional
network usage by doing this.
2017-03-25 14:18:23 -07:00
Joshua Pan
16b2313165 muting_ui.js: Remove any popups when unmuting. 2017-03-25 12:49:14 -07:00
Joshua Pan
0ce38b6a92 Add documentation for M hotkey. 2017-03-25 09:42:49 -07:00
Joshua Pan
7adf70e5ad Add node tests for M hotkey. 2017-03-25 09:42:49 -07:00
Joshua Pan
76e84288d9 Add M hotkey to toggle mute/unmute topics.
Get rid of current_msg_list.selected_message() redundancy.
2017-03-25 09:42:49 -07:00
Joshua Pan
dc9f83005f Add toggle_mute to muting_ui.js. 2017-03-25 09:42:49 -07:00
Joshua Pan
32837804d8 Extract stream_popover.topic_ops to muting_ui.js. 2017-03-25 09:42:49 -07:00
Brock Whittaker
efd72d3338 Modify lightbox to only display valid images and YT Videos.
This modifies the lightbox to only display images inside the
".message_inline_image" class, rather than all images inside the
message body, which currently includes things like the bot icon.
2017-03-25 09:19:26 -07:00
Steve Howell
b3e4aa4c44 reactions: Downgrade blueslip error to a warning.
When we get a server error for adding/removing a reaction, we
no longer make a blueslip error, since it is somewhat common for
users to retry actions before the server sends an event.  The
code comment that is part of this commit explains this further.

Fixes #4290.
2017-03-24 18:24:15 -07:00
Sumana Harihareswara
d4b56df5e4 docs: Guide developer questions to GitHub and chat. 2017-03-24 12:07:14 -07:00
Umair Khan
f7860bca48 backends.py: Don't pass mutable default arguments.
Values of mutable default arguments are shared across all function
invocations. See
https://pythonconquerstheuniverse.wordpress.com/2012/02/15/mutable-default-arguments/
for further details.
2017-03-24 10:59:32 -07:00
Tim Abbott
7bcf24d39c test_management_commands: Reset settings.RUNNING_INSIDE_TORNADO.
This fixes a leak of this setting change that resulted from the
unusual way that our Tornado system sets this variable early in the
management command.

Fixes #3685.
2017-03-23 23:56:10 -07:00
Tim Abbott
3617ebfd41 api: Rename get_old_messages to get_messages in the backend.
Fixes #1315.
2017-03-23 23:52:44 -07:00
wizsid11
95789eb879 Add Slack webhook.
Adds a new webhook integration for Slack to receive messages
from one's Slack team's public channels.
Contains negative tests for broken, missing or invalid data.

Allows two different option for integration:
1. Receive notification on a single stream with different topics
for each of Slack's public channels.
2. Receive notification on different streams for each of Slack's
public channels.

Steps to choose between the two options is described in the documentation.

Fixes #3569.
2017-03-23 23:32:38 -07:00
Tomasz Kolek
be0a2cb20b Add basecamp3 webhook integration.
Fixes: #3949.
2017-03-23 23:28:53 -07:00
Tomasz Kolek
09f5180da9 github_webhook: Return 200 OK if event is not supported.
Change raising exception when event is not supported to just logging it.
2017-03-23 23:26:55 -07:00
Tomasz Kolek
fcd091132d jira: Return 200 OK if event is not supported. 2017-03-23 23:26:55 -07:00
Tim Abbott
a6ae546f59 test_events: Bring zerver/lib/events.py to 100% coverage. 2017-03-23 22:43:10 -07:00
Tim Abbott
0c16cc1c1e test_events: Add a test for do_refer_friend. 2017-03-23 22:43:10 -07:00
Tim Abbott
055a18e71f test_events: Add a test for do_update_embedded_data. 2017-03-23 22:43:10 -07:00
Tim Abbott
eb19a25aba events: Fix races in stream creation event and add tests.
This fixes 2 issues:
* Being added to an invite_only stream did not correctly update the
  "streams" key of the initial state.

* Once that's resolved, subscribe_to_stream when called on a
  nonexistant stream would both send a "create" event (from
  create_stream_if_needed) and an "occupy" event (from
  bulk_add_subscriptions).

  The second event should just be suppressed in that case, and this
  implements that suppression.
2017-03-23 22:43:09 -07:00
Tim Abbott
8eb020d190 test_events: Add a test for do_update_muted_topic. 2017-03-23 22:27:39 -07:00
Tim Abbott
dbe3ea59aa test_events: Add a failing presence test.
Apparently our presence real-time sync is slightly broken; this test
at least reveals that fact.
2017-03-23 22:27:39 -07:00
Tim Abbott
d1760a1bb9 validators: Add check_float validator. 2017-03-23 21:23:41 -07:00
Tim Abbott
12a6913bbf test_events: Add a test for do_update_message_flags. 2017-03-23 21:11:33 -07:00
Tim Abbott
2b905d242d events: Fix timezone realm-time sync and add test. 2017-03-23 19:11:34 -07:00
Tim Abbott
86e3d1effc events: Fix default language realm-time sync and add test.
We previously didn't apply the default language event change
correctly.

Not super important as a bug, since we require the user to reload the
browser for their changes to take effect, but this will save time if
we ever change that.
2017-03-23 19:08:17 -07:00
Tim Abbott
99515c2d34 test_events: Add tests for default streams being None. 2017-03-23 19:04:13 -07:00
Tim Abbott
adcf8263d6 tests: Fix passing non-unicode strings to do_set_realm_property.
This fixes test failures on Python 3 caused by
a98bce98c6.
2017-03-23 18:37:12 -07:00
Tim Abbott
35f3070927 requirements: Move incorrectly filed dependencies.
These are only used in development, and should never have been added
to common.txt.
2017-03-23 18:14:20 -07:00
Tim Abbott
a98bce98c6 realm: Add registry of realm property types.
This makes it possible for us to do some convenient validation for
developers, checking whether the correct types are passed for each
each realm property.
2017-03-23 17:55:50 -07:00
Sarah Stringer
09f66b5c6d actions: Add do_set_realm_property function and migrate to it.
zerver/lib/actions: removed do_set_realm_* functions and added
do_set_realm_property, which takes in a realm object and the name and
value of an attribute to update on that realm.

zerver/tests/test_events.py: refactored realm tests with
do_set_realm_property.

Kept the do_set_realm_authentication_methods and
do_set_realm_message_editing functions because their function
signatures are different.

Addresses part of issue #3854.
2017-03-23 17:52:45 -07:00
Umair Khan
2d4a1f93ff testing: Bring zproject.backends coverage to 100%. 2017-03-23 17:12:58 -07:00
Umair Khan
2dc2a6b705 github: Redirect to login page if invalid email. 2017-03-23 17:12:58 -07:00
Umair Khan
30c1e2245e github: Add docstrings to functions.
Docstring added to:
* auth_complete
* do_auth
2017-03-23 17:12:58 -07:00
Umair Khan
029a4e5696 backends.py: Update comment in process_do_auth. 2017-03-23 17:12:58 -07:00
Tim Abbott
debb00b190 lint: Fix get_stream lint error in actions.py. 2017-03-23 15:50:33 -07:00
Tim Abbott
36988f9375 mypy: Fix Optional typing issues in tex.py. 2017-03-23 15:49:08 -07:00
Akash Kothawale
4c2bfae83e get_stream: Throw DoesNotExist if stream is not found.
This makes get_stream match get_realm, get_user_profile_by_email,
etc., in interface, and is more convenient for mypy annotations
because `get_stream` now doesn't return an Optional[Stream].
2017-03-23 15:42:00 -07:00
Tim Abbott
69323d12c9 Fix click message_content covering bottom half of avatar.
This causes clicks to correctly hit the avatar an open the profile
popover.

Fixes #4251.
2017-03-23 15:22:06 -07:00
Aditya Bansal
17a4c5d0d8 Fix horizontal scroll for super long lines in bullet lists.
Fixes: #4245.
2017-03-23 15:19:28 -07:00
Moritz Neeb
9866805937 docs: fix a typo in hashchange.js 2017-03-23 15:16:02 -07:00
Moritz Neeb
65e8d66376 docs: hashchange-system: add more detail and fix some sentences.
Edited slightly by tabbott for typos and line-wrapping.
2017-03-23 15:15:44 -07:00
Alexander Trost
0fb6779899 docker: Make user and dbname configurable in process_fts_updates. 2017-03-23 14:28:21 -07:00
Tim Abbott
36b9c5792a compose: Move hotkey out of translation tags in title.
The hotkey will be the same anywhere, and this saves an extra couple
strings that translators shouldn't need to have to translate.
2017-03-23 14:03:09 -07:00
Tim Abbott
e16b082b70 casper: Attempt to fix flakiness in new reload test. 2017-03-23 13:56:59 -07:00
Rishi Gupta
b1afafb8d5 compose.html: Fix hotkey advice for New Private Message button. 2017-03-23 13:16:15 -07:00
Tim Abbott
06492738b5 dev: Expose coverage and built documentation to web.
This makes it much more convenient for developers to access coverage
and built developer documentation.
2017-03-23 13:10:06 -07:00
Tim Abbott
97e844e97c test_notifications: Don't pass a user_profile to client_patch.
This fixes a JSON overflow error when producing URL coverage reports.
2017-03-23 13:08:49 -07:00
Tim Abbott
49f5be1dba hotkey: Extend tests for message_view_only_keys. 2017-03-23 11:38:37 -07:00
Joshua Pan
f40b43a491 hotkeys: Add hotkey G an alias for End.
Fixes #4195.
2017-03-23 11:38:36 -07:00
Tim Abbott
5d030e9173 casper: Add test for the reload hashchange logic. 2017-03-22 23:06:08 -07:00
Tim Abbott
04db0b5df0 reload: Fix passing data to next browser session.
Apparently, Django's CSRF protection mechanism changed at some point,
and now we get a different CSRF token every time the webapp is loaded.
This, in turn, caused our reload logic to avoid losing state to be
completely ineffective, since the CSRF check in reload.initialize
always failed.

We fix this in a secure fashion by passing the reload instructions
from the browser to its reloaded self via localstorage, keyed by a
randomly generated token.  The token randomization is primarily
relevant for handling several Zulip tabs in the same browser, but also
servers to make it very difficult for an attacker to ever trigger this
code path by redirecting a browser to `/#reload` URLs.

Fixes #3411.
Fixes #3687.
2017-03-22 22:46:54 -07:00
Tim Abbott
64acf84ab1 reload: Save narrow when event queues expire.
Along with the issues with our reload data passing system that are
fixed in the next commit, this is responsible for #3411.
2017-03-22 22:28:35 -07:00
Tim Abbott
ee4b948873 bankruptcy: Fix narrow being lost on declaring bankruptcy.
This was actually being done in 2 ways: via not saving the narrow in
the reload and second through calling `change_tab_to('#home')`.  The
code is so ancient that it seems unlikely that this behavior was still
intentional.

Fixes part of #3687 (the remainder is fixed in a few commits).
2017-03-22 22:28:18 -07:00
Tim Abbott
37ac0e6e6d server_events: Remove obsolete 'tool old' handler.
This error predates the transition to an event queue system and hasn't
been possible for years.
2017-03-22 21:16:39 -07:00
Tim Abbott
61e6ed8c31 bankruptcy: Fix clicking outside bankruptcy modal.
Previously, this would leave the unread UI disabled forever, showing 0
unread counts for anything, which was a super confusing failure mode.
2017-03-22 20:50:44 -07:00
Tim Abbott
977e7b0fdc unread: Move bankruptcy code out of click_handlers.js. 2017-03-22 20:49:05 -07:00
Tim Abbott
f3af0fe635 reactions: Fix reacting to messages on streams you're not subscribed to.
We use the same strategy Zulip already uses for starred messages,
namely, creating a new UserMessage row with the "historical" flag set
(which basically means Zulip can ignore this row for most purposes
that use UserMessage rows).  The historical flag is ignored, however,
in determining which users' browsers to notify about new reactions,
and thus the user will get to see the reaction appear when they click
a message (and any reactions other users later add, as well!).

There's still something of a race here, in that if some users react to
a message while the user is looking at the unsubscribed stream but
before the user reacts to that message, those reactions will not be
displayed to that user (so counts will be a bit lower, or something).
This race feels small enough to ignore for now.

Fixes #3345.
2017-03-22 20:22:13 -07:00
Tim Abbott
60326ca94c test_events: Add reaction tests. 2017-03-22 20:22:02 -07:00
Tim Abbott
0963f2d518 reactions: Extract notify_reaction_update. 2017-03-22 20:22:02 -07:00
Tim Abbott
ce2c3fbb06 requirements: Install api bindings in production. 2017-03-22 19:33:51 -07:00
Tim Abbott
1f89058023 Fix broken size for message actions popover.
This fixes a regression introduced in
23a5f56023 where the `.popover-inner`
CSS wasn't scoped properly.
2017-03-22 16:44:23 -07:00
Tim Abbott
ccb38a1e9c compose: Fix missing opts argument to show_box.
This fixes a regression in the recent compose.get_focus_area
refactoring that I did.
2017-03-22 16:32:53 -07:00
hackerkid
97bd9d5186 Fix positioning of message-info-popover. 2017-03-22 16:04:38 -07:00
hackerkid
ed72ee476f Make user_popover use user_info_popover template. 2017-03-22 16:04:38 -07:00
hackerkid
b2fc8d6fa2 Rename message_info_popover* templates to user_info_popover*. 2017-03-22 16:04:38 -07:00
hackerkid
23a5f56023 Add sender avatar in message popover. 2017-03-22 16:04:38 -07:00
hackerkid
3ac8f52a73 Remove title of message info popup. 2017-03-22 16:04:38 -07:00
hackerkid
32bc5893d0 Remove arrow from message info popover by providing template.
Provide custom template (user_info_popover.handlebars) to message info popover.
2017-03-22 16:04:38 -07:00
Tim Abbott
2a5e600623 glossary: Add a few comment useful terms. 2017-03-22 15:49:20 -07:00
Moritz Neeb
b96d18eb6f documentation: explain the term "bankruptcy". 2017-03-22 15:49:19 -07:00
Tim Abbott
67a4ce99ee tutorial: Disable tutorial for default development users.
You can always make a new user if you need to test the tutorial, and
this will save a bunch of developer time ignoring the tutorial popup.
2017-03-22 15:30:36 -07:00
Tim Abbott
2a5269baa9 docs: Document the frontend hashchange system. 2017-03-22 15:21:36 -07:00
hollywoodno
d6716838ad bugdown: Remove trailing whitespace on fence code blocks.
This fixes fenced code blocks that are copy-pasted from certain
clients having trailing whitespace anoyingly often.

Fixes #3998.
2017-03-22 14:17:34 -07:00
Brock Whittaker
5ed482cf2c compose: Apply consistent styling for compose buttons.
This applies the consistent :hover effect for all compose buttons.

Fixes: #4239.
2017-03-22 13:15:44 -07:00
Tim Abbott
d39b2e116b settings: Disable password strength checking in development. 2017-03-22 13:14:20 -07:00
Tim Abbott
0fec03f8bb test_docs: Fix normal users test text. 2017-03-22 13:14:19 -07:00
Tim Abbott
3d3f9bc58e devlogin: Link to the normal login page. 2017-03-22 13:03:45 -07:00
sinwar
397e9c109e auth: Separate development login from main login page.
This allows us to enable EmailAuthBackend by default in development
without cluttering the development login experience.

Fixes #3652.
2017-03-22 12:54:30 -07:00
Rishi Gupta
4c88b3f5da logging_util: Fix timezone-naive datetime being compared to aware datetime.
Fixes regression in 3d07ac0.
2017-03-22 12:51:58 -07:00
Brock Whittaker
dbcd19bcfa streams: Add hotkey for content-editable enter.
When you enter, it should click the checkmark, which would save the
current input of the input section.
2017-03-22 12:21:21 -07:00
Brock Whittaker
d21fe68e9e streams: Fix content-editable cursor shifting to beginning. 2017-03-22 12:21:08 -07:00
Raghav Jajodia
956106ae92 streams: Fix closing of content-editable area on escape key press.
Pressing Escape key while editing stream description now closes
the editing.
Fixes #4202.
2017-03-22 12:19:59 -07:00
Raghav Jajodia
9a339a7053 streams: Prevent cursor jump to the end of editing stream-descr.
This prevents the cursor to jump at the end of the content-editable
area when the user types in the middle.

Fixes #4202.
2017-03-22 12:19:59 -07:00
Umair Khan
0fc946aef4 testing: Add reverse option to test runner. 2017-03-22 12:07:21 -07:00
Umair Khan
3c0f341eb7 test_subs.py: Change assert_max_length to assert_length. 2017-03-22 12:07:21 -07:00
Umair Khan
804c62045f testing: Flush API_KEYS before every test.
This makes our test performance for each test more consistent.
2017-03-22 12:07:06 -07:00
Umair Khan
ff8ab054da testing: Fix query count for test_bulk_subscribe_MIT.
test_subs.SubscriptionAPITest.test_bulk_subscribe_MIT fails when it is
run individually.
2017-03-22 12:07:06 -07:00
Umair Khan
8431ceace2 testing: Serialize BotTest with upload tests. 2017-03-22 11:59:30 -07:00
Umair Khan
2f243d8808 testing: Control parallelism through cmd args. 2017-03-22 11:59:30 -07:00
Raghav Jajodia
9707c74f33 message_edit: Added copy to clipboard button.
A copy-to-clipboard button is added over message-edit textarea.
Closes #3239.
2017-03-22 11:00:18 -07:00
Steve Howell
2991c19fea Extract typing indicator inbound timing logic.
We now track our inbound timing events using code in
typing_data.js.

This code may be a little more robust with variations on how
recipients are represented in events, although there are no known
bugs here.
2017-03-22 08:20:21 -07:00
Steve Howell
4fb8339954 Extract typing_events.js. 2017-03-22 07:29:42 -07:00
Steve Howell
cde1861655 typing indicators: Validate PM emails. 2017-03-22 07:01:20 -07:00
Steve Howell
1ec392a18e Extract compose.get_invalid_recipient_emails(). 2017-03-22 07:01:20 -07:00
Steve Howell
84b31a5532 typing indicators: Limit to PM conversations.
We now only send outbound typing indicators if we are
composing a private message.
2017-03-22 07:01:20 -07:00
Steve Howell
642be6ad18 Revamp state tracking for outbound typing indicators.
This change moves most of the logic related to starting and
stopping outbound typing indicators to a new module called
typing_status.js that is heavily unit tested.

While this was in some sense a rewrite, the logic was mostly
inspired by the existing code.

This change does fix one known bug, which is that when we
were changing recipients before (while typing was active), we
were not stopping and starting typing indicators.  This was
a fairly minor bug, since usually users leave the compose
box to change recipients, and we would do stop/start under
that scenario.  Now we also handle the case where the user
does not leave the compose box to change recipients.
2017-03-22 07:01:20 -07:00
Steve Howell
8c0a1bddb0 linter: Deprecate ui.report_success/error(). 2017-03-22 06:57:23 -07:00
Steve Howell
f89c9d6629 Avoid deprecated report_success() call.
We are moving to ui_report to break dependencies.
2017-03-22 06:53:21 -07:00
Tim Abbott
2076338eaa mark_subscribed: Add a blueslip check for color code path.
This code path might be unused, and it seems worth verifying, since if
it is, we can delete some extra complexity.
2017-03-21 23:36:47 -07:00
Tim Abbott
01904385a4 Fix thrashing color when resubscribing to a stream.
Previously, we would let the backend pick a color and send it to the
frontend; then the frontend would ignore that color and pick a
different color and send it to the backend, which would in turn resync
to us.

Fixes #3572.
Fixes #3858.
2017-03-21 23:35:50 -07:00
Tim Abbott
832aa398b0 subscription_settings: Move email address into toggled area. 2017-03-21 23:09:32 -07:00
Tim Abbott
1ad0d35966 subs: Clean up ancient collapsing logic. 2017-03-21 23:09:32 -07:00
Tim Abbott
bfc67f6602 subs: Toggle notification settings on subscribe. 2017-03-21 23:09:32 -07:00
Tim Abbott
dfddea77b7 subscriptions: Show stream settings after toggling checkbox.
Based on Aakash Tiyagi's work in #4026.

Fixes #3971.
2017-03-21 23:09:32 -07:00
Tim Abbott
9347fc4742 subs: Move show_stream_row earlier in file. 2017-03-21 23:09:29 -07:00
Tim Abbott
a7610c8b7e subs: Clarify show_stream_row arguments. 2017-03-21 23:07:28 -07:00
Tim Abbott
e70bf13bef subs: Extract setup_subscriptions_stream_hash. 2017-03-21 22:17:50 -07:00
James Wang
c13809c83f invite: Display and check default streams in invite modal.
This fixes two bugs:

* If a user is not subscribed to a default stream, he or she would not
  be have the option to invite users to that default stream.
* The initial streams checked in the invite modal were the
  non-invite-only streams the user was subscribed to, not their
  default streams.

Fixes: #4209.
2017-03-21 20:56:34 -07:00
digi0ps
a765b6e781 settings: Fix user edit form not being shown.
Added an if condition to checks whether person is a bot before fetching
information about bot owner in *static/js/admin.js*.
2017-03-21 20:52:11 -07:00
Cynthia Lin
1dfac12c4b hotkeys: Add arrow key navigation in streams/subscriptions menu.
Fixes #4198.
2017-03-21 20:32:28 -07:00
Saumya Bhatnagar
1a6efc9705 README: Update GSoC section to mention android plan. 2017-03-21 20:16:27 -07:00
Eeshan Garg
b8f71c5d24 Document how to set up an Asana integration via Zapier.
Fixes #3948.
2017-03-21 19:56:47 -07:00
Steve Howell
f6c8f4de43 Upgrade jquery to 2.2.3.
We were at 1.12.1.  Versions 1.12 and 2.2 have the same API, and
2.x basically removes some compatibility for old browser versions.
2.2.3 was the last bug release for 2.2, and it was released in
April 2016.
2017-03-21 18:57:03 -07:00
Steve Howell
bd04ea02d3 Use new JS data layer for typing notifications.
The old code may have had some subtle bugs related to sorting of
ids or stringification or failed Dict lookups.  The new data
layer should be more robust.  We had some tracebacks recently
from the old code, and they should go away now.
2017-03-21 17:24:40 -07:00
Steve Howell
67a2094ed1 Add typing_data.js, which can track users who are typing.
(A subsequent commit will actually integrate this into the app.)
2017-03-21 17:24:40 -07:00
Tim Abbott
8b9e78e486 compose: Extract and test get_focus_area. 2017-03-21 17:24:40 -07:00
Tim Abbott
82ec083066 compose: Fix new topic button behavior in home view. 2017-03-21 17:24:40 -07:00
Yago González
34a9e1ae11 markdown: Add TeX typesetting support.
Co-authored-by: Reid Barton <rwbarton@gmail.com>

Fixes #2056.
2017-03-21 16:40:00 -07:00
Rishi Gupta
caef5332d5 mailchimp: Fix error in add_users_to_mailing_list.py.
Old behavior is a holdover from development testing.
2017-03-21 16:13:00 -07:00
Tim Abbott
993276b882 test_upload: Add tests for realm icon URL scheme. 2017-03-21 16:12:04 -07:00
Tim Abbott
8775a22663 avatar: Fix buggy avatar URL scheme with S3 backend.
Also adds tests for the avatar URL scheme.
2017-03-21 16:12:04 -07:00
Ayush Jain
bddcfb1c96 Add realm-level settings to control inline image and url preview.
This gives users more control in case they don't want previews,
especially for the "previews of linked websites" feature.

Fixes: #2640.
2017-03-21 15:46:17 -07:00
Brock Whittaker
a27f8f2f30 Fix up YouTube embed issues and styling.
This fixes the styling to stay on the screen of most reasonably sized
monitors along with extending the JavaScript code to allow for the
video to be keyed to in the lightbox.
2017-03-21 14:28:13 -07:00
Brock Whittaker
1b31f9be38 Move lightbox events to lightbox.js from clickhandlers.js.
This consolidates lightbox logic to lightbox.js.
2017-03-21 14:28:13 -07:00
Brock Whittaker
9c38dc84a7 Change two console.log statements to one with prefixed newline.
The console.log statement that is empty can be replaced with just a
single newline.
2017-03-21 14:28:13 -07:00
Brock Whittaker
920b082e08 Fix animation speed bug with > going at a different pace than text.
The issue is that stacking the two transitions appears to make the
::after pseudo-element slower for some reason than its parent. This
visually appears to fix it.
2017-03-21 14:10:27 -07:00
Yago González
0c6251e58d docs: Add reference to tilde-fenced code blocks. 2017-03-21 13:58:40 -07:00
Brock Whittaker
5e0a906f84 Fixes for /integrations/ page.
This fixes the hubot text that still stays when you transition to
integration details along with fixing the first animation that is
choppy and previews briefly before fading in.

Fixes #4210.
2017-03-21 13:55:59 -07:00
adnrs96
b3cbb13a79 linter: Add support for automatic checking for 4 space indents in CSS.
In this commit we modify our CSS parser not only to render the text from
a given CSS tokens produced but also enforce 4 space indentation on it.
Also we enforce some basic rules we would like our CSS to follow such as
* Always have "\n" in between the starting of body({) and body itself
  and ending of the body and the closing of body(}).
* Use 4 space indents while having but something within the block
  structure ( { .... } ).
* Have single space after ',' in between multiple selectors.
* Have only a single space in between selector and the starting of
  block structure ({ ... }) if block structure starts on same line as
  of selector.
  eg. body {
          body content here
      }
  Notice single space between 'body' and '{'.

Fixes: #1659.
2017-03-21 13:40:05 -07:00
adnrs96
257187a239 Clean zulip.css to use 4 space indents. 2017-03-21 13:40:05 -07:00
adnrs96
a91012bd70 Move thirdparty-fonts.css from static/styles to static/third. 2017-03-21 13:40:05 -07:00
Tim Abbott
17597e2ddf register: Fix maximum length of realm name field. 2017-03-21 11:04:22 -07:00
Umair Khan
a2aeddba6b testing: Add infrastructure for running backend tests in parallel.
This doesn't yet provide an option to actually run the backend tests
parallelized yet.
2017-03-21 10:59:12 -07:00
Tim Abbott
6d452e87a5 context_processors: Handle requests without user set.
If `render()` is called from middleware that runs before the
authentication middleware, then this code path will be called with a
request object where request.user is not yet set.  Handle this by
providing a reasonable error message.
2017-03-21 10:06:39 -07:00
Steve Howell
36b29a966e Add roadmap feature to js-dep-visualizer.
The js-dep-visualizer tool now attempts to find a set of edges
to remove from a call graph that would reduce it to having only
trivial mutual dependencies, and it produces a roadmap of the
changes that need to happen.

If the tool can't reduce the graph all the way, it still produces
a DOT file that can be visualized.

This fix also has some significant code cleanup.
2017-03-21 07:39:30 -07:00
Steve Howell
c87c67c33f js deps: Fix ui.report_success(). 2017-03-21 07:39:30 -07:00
Tim Abbott
a474f4359d tests: Set maxDiff to None unconditionally. 2017-03-21 07:34:16 -07:00
Tim Abbott
8041ebf579 mypy: Annotate maxDiff variable. 2017-03-21 07:31:37 -07:00
Tim Abbott
c2c02ea4da middleware: Fix typo in render_to_response migration.
This fixes a 500 on the invalid realm page.
2017-03-21 07:30:28 -07:00
K.Kanakhin
831a467fa3 upload-widget: Correct file input clearing.
Replacing file input doesn't work for value clearing. The best
way is to clean value directly, which excludes accidentally adding
wrong file after upload-widget validation error.
2017-03-21 00:59:17 -07:00
adnrs96
8ae35211b5 migration: Sync sizes for existing Attachment objects with actual files.
Tweaked by tabbott to add a nop reverse migration.

Fixes #3883.
2017-03-21 00:53:22 -07:00
Tim Abbott
20a7609018 analytics: Rename message count types to use standard Zulip casing. 2017-03-21 00:09:54 -07:00
Tim Abbott
aa7e4fec35 messages: Require join with zerver_message if use_first_unread_anchor.
This fixes a 500 bug where the RN mobile app would simply fail to load
old messages if use_first_unread_anchor was not set.
2017-03-21 00:02:46 -07:00
Tim Abbott
ee2e6a31b1 reactions: Close popover on escape even with input focused.
This makes it much more convenient to close the emoji reactions
popover after opening it with the hotkeys.

It'd be great if we had a test suite for escape so that we could add
tests for this.

Fixes part of #4197.
2017-03-20 23:51:45 -07:00
Tim Abbott
cebaf140c6 subs: Fix stream descriptions rendering on creation.
This is kinda hacky and probably not how we want this to work
long-term, but I think it's a larger refactoring project to make this
part of the model make sense.
2017-03-20 23:25:43 -07:00
Tim Abbott
32b77d970b casper: Fix missing casper.then in subscriptions tests. 2017-03-20 23:21:38 -07:00
Tim Abbott
a903d28d78 subs: fix missing ; introduced by rebase error. 2017-03-20 23:19:14 -07:00
Brock Whittaker
d89ea13358 portico: Redesign apps page. 2017-03-20 23:08:24 -07:00
Brock Whittaker
4b64ff3752 Change from checking landing page by href to pathname.
Checking by href is a flawed approach due to the fact that hashes
are included in the href and will throw off the results of
returning the last block in a path. The window.location.pathname
property is a much better indicator of the current path.
2017-03-20 23:08:24 -07:00
Raghav Jajodia
2d4ba0fde5 stream_data: Linkify URL in stream description.
If a url is present in stream description, it will be
rendered as a clickable link under /streams page.

Tweaked by tabbott to use the separate rendered_description element to
avoid duplicate rendering and to live-update.

Fixes #1435.
2017-03-20 22:25:03 -07:00
Jeremy Philemon
d13901c22b Changed "Choose a user" to "Click on a user to log in".
- Set the width of .login-page-header to 100% to make it responsive on
smaller screens. Previously, the header went off screen for screen
widths <360 px.

Tweaked by tabbott to remove unnecessary translation tags.

Fixes #4106.
2017-03-20 21:55:11 -07:00
Tim Abbott
239f4e474e zephyr_mirror: Simplify process for finding backend script. 2017-03-20 21:52:04 -07:00
Tim Abbott
848da74e3c sync_public_streams: Use option group for arguments. 2017-03-20 21:52:04 -07:00
Tim Abbott
97808d2a51 check-mirror: Remove unnecessary zulip_user variable. 2017-03-20 21:52:04 -07:00
Tim Abbott
96fb78609b check-mirroring: Remove api.zulip.com hardcoding. 2017-03-20 21:52:04 -07:00
Yago González
156b204015 echo: Remove impossible 'quote' 4-space-indented code block type.
Since it's not possible to manually set the language in 4-space-indented
code blocks, there's no point in checking if these blocks' type is
"quote".
2017-03-20 21:49:22 -07:00
Brock Whittaker
6115ef3427 Disable web sockets for mobile devices.
iOS doesn’t seem to play nice with the web socket library we are using
them, so disable use of websockets for sending messages until we can
fix that.

Fixes #2306.
2017-03-20 21:44:23 -07:00
Mahim Goyal
91252b3909 Fix alignment in actions drop-down menu.
Fixes: #3010.
2017-03-20 21:21:53 -07:00
Steve Howell
7bc2df6a91 Put popular emojis in top row of reactions. 2017-03-20 20:23:32 -07:00
Steve Howell
2296bf5859 Clean up rendering code for reaction popovers.
Instead of passing in a hash to template whose keys are a
mixture of records and strings, we now pass in an
array of records.  This also removes a spurious if condition
in the template that was a result of the janky data structure.
2017-03-20 20:23:32 -07:00
hollywoodno
dd067c761a analytics: Separate private messages from group private messages.
This makes it possible for our graphs to show the group private
message counts as separate from 1:1 private messages.

Fixes #4102.
2017-03-20 11:46:29 -07:00
Tim Abbott
0c0e5397c4 analytics: Fix nondeterministic ordering of labels. 2017-03-20 11:39:08 -07:00
tejaskasetty
02bd5bedce Fix duplicate emoji entries in compose emoji picker.
We were incorrectly appending all the emoji into the emoji picker
every time it was opened, rather than just once.

Note by tabbott: Arguably this isn't the right fix, in that it might
be better to just render the emoji picker once at the beginning.  But
this definitely fixes the bug.

Fixes #3952.
2017-03-20 10:46:20 -07:00
Steve Howell
29412cd06b bug fix: Fix missing return statement in get_filter_li().
This was regressed in 89e17e1aee.

At least one of the symptoms was that we weren't updating the
activity list properly.  This could also cause tracebacks in
compose fade logic.
2017-03-20 09:49:19 -07:00
Tim Abbott
b701062d16 Update + hotkey to use the keypress mechanism.
This fixes in issue where the new + hotkey only worked if you hit
shift+=, not if you pressed an actual "+" key on the keyboard.

Fixes #4182.
2017-03-20 09:46:26 -07:00
Umair Khan
38572311f9 linter: Add a rule to check render_to_response. 2017-03-20 07:54:28 -07:00
Tim Abbott
24c2e62ae1 capitalization: Add exception for selected message.
This fixes a test that's been failing overnight.
2017-03-20 07:52:58 -07:00
Steven Ganz
5041d86db0 tests: Add several missing tests to test_events.
This fixes part of #3633.

Extracted by tabbott from #4162 as ready to merge now.
2017-03-19 23:12:12 -07:00
Jeremy Philemon
2d0ee8a83f Information modals are now responsive on smaller screens.
- Added a media query for `max-width: 768px` where the changes in the
css will take place.
- This fix also makes the navigation menu responsive.

Tweaked by tabbott to better contain the CSS to this module.

Fixes #4022.
2017-03-19 23:00:40 -07:00
Tim Abbott
ceeb95ebb1 tests: Fix missing test coverage for /json/realm.
In aa880b0419, we used the raw
do_set_realm_description method rather than calling the API, which
meant that the API success path wasn't actually tested.
2017-03-19 22:49:16 -07:00
Yago González
df94719707 lint: Ban redundant linkified URLs. 2017-03-19 22:46:25 -07:00
Jacob Hurwitz
eb1843fd37 [zephyr_mirror] add support for zcrypt'ed classes with colons
The regex used for parsing .crypt-table didn't allow colons in class
names. This commit changes the [^:] token with \S, meaning that class
names can now contain colons but can no longer contain whitespace.

I think this should be fine, since zcrypt is only used for MIT zephyr,
where (by convention) class names do not contain whitespace.

Additionally, it should not be possible for us to accidentally consume a
field-separating colon as part of the class capture group because the
regex enforces that all field-separating colons are followed by one or
more whitespace characters, whereas the class name cannot contain
whitespace.
2017-03-19 22:30:21 -07:00
Tim Abbott
81194df65d test_bots: Add stream is not None asserts. 2017-03-19 22:26:25 -07:00
Tim Abbott
e2eeef5118 recipient_for_emails: Fix confusing type reuse. 2017-03-19 22:26:25 -07:00
Tim Abbott
7e5d5b5cce mypy: Clean up repetition in test_realm_aliases.
The assert added in this refactoring addresses a mypy issue with
strict optional since get_realm_by_email_domain might return None.
2017-03-19 22:26:25 -07:00
Tim Abbott
5b0ff2a69a mypy: Fix some strict-optional related issues. 2017-03-19 22:26:25 -07:00
Tim Abbott
2b62c4fa38 mypy: Fix missing annotation in Tornado handlers.
This was accidentally removed in
9866124b78, but is needed on the current
mypy version.
2017-03-19 22:26:25 -07:00
Brock Whittaker
2775707a67 hotkeys: Add lightbox image feed with controls.
This adds an image feed that you can scroll through with hotkeys
in the lightbox.

The left and right arrow keys along with the left and right arrows
will go to the prev/next image, and clicking on an image will also
take a user to that image.
2017-03-19 22:11:38 -07:00
Brock Whittaker
fa5a093738 hotkeys: Add keyboard shortcut for opening the gear menu.
This adds the shortcut “g” for opening the gear menu.
2017-03-19 22:08:21 -07:00
Brock Whittaker
2c28e519d8 Fix un-tab-able links in gear menu.
This fixes some un-tab-able links in the gear menu to have a tabindex
so that they can be tabbed over with shortcuts.
2017-03-19 22:06:27 -07:00
Tim Abbott
70a0df73ba tests: Add some documentation for the hotkey node tests. 2017-03-19 22:06:27 -07:00
Brock Whittaker
32d1e64530 hotkey: Improve clarity of error messages in hotkeys tests.
This will provide a clearer error message than a ReferenceError as to
what's wrong when the wrong values are in hotkey tests.
2017-03-19 22:06:27 -07:00
Tim Abbott
8fa60cf77c py3: Remove use of typing.Deque.
Apparently this is only available in ultra-modern versions of Python 3?
2017-03-19 21:39:54 -07:00
Steve Howell
edb8b0cb5e Improve js-dep-visualizer.
This adds a report of nodes, handles some errors better, adds
some helpful output, cleans up some abspath calls, and
updates which modules and/or dependencies we temporarily are
ignoring for the report.
2017-03-19 21:03:45 -07:00
Steve Howell
fd856d728c Extract message_util.js 2017-03-19 21:03:45 -07:00
Steve Howell
8d3d70984d Extract message_events.js. 2017-03-19 21:03:45 -07:00
Steve Howell
1114c8bf62 Extract message_fetch.js. 2017-03-19 21:03:45 -07:00
Tim Abbott
9866124b78 mypy: Fix some new errors flagged by latest mypy master.
Mostly list -> List bugs in annotations.
2017-03-19 21:03:45 -07:00
wangjames
e0813c7288 collapse: Fix new messages not being collapsed consistently.
This fixes a bug where newly received very-long messages would only
sometimes be collapsed properly until a second message arrived
(whether it did the right thing dependened on whether the new message
had the same recipient or a different recipient from other arriving
messages).

Apparently, we correctly called condense.condense_and_collapse in all
but one of the codepaths of `render` that add new messages.  This
adds a call on the missing codepath.

Fixes #3978.
2017-03-19 20:39:21 -07:00
Tim Abbott
7e74af3cea docs: Shorten some keyboard shortcut descriptions.
In particular, this fixes some unnecessarily multi-line descriptions
that made the keyboard shortcuts display look bad.
2017-03-19 14:45:16 -07:00
Joshua Pan
93609cc39d Update shortcuts modal and documentation with reaction hotkeys. 2017-03-19 14:45:00 -07:00
Joshua Pan
5ec21e2230 hotkey.js: Add opening reactions hotkey.
Add frontend tests for ":" hotkey.

Fixes #3911.
2017-03-19 14:37:05 -07:00
Joshua Pan
b600e4d594 Pressing enter in reactions search picks first reaction. 2017-03-19 14:36:34 -07:00
Joshua Pan
9c3d63a80b Add '+' hotkey to add thumbs up reaction.
Fixes #3910.
2017-03-19 14:36:33 -07:00
Joshua Pan
c8f2da3f3e reactions.js: Refactor reaction_popover_reaction_on_click. 2017-03-19 14:25:10 -07:00
Elliott Jin
356f57c831 refactor: Simplify pattern for adding external linters. 2017-03-19 14:13:38 -07:00
Elliott Jin
ac488fd45f tools: Don't lint in pre-commit hook if no files changed. 2017-03-19 14:13:38 -07:00
Elliott Jin
5ada385b91 refactor: Check for empty list with len(X) == 0 instead of not X. 2017-03-19 14:13:38 -07:00
Elliott Jin
750769f637 tools: Only lint changed template files in pre-commit hook. 2017-03-19 14:13:38 -07:00
Elliott Jin
2e246a936f tools: Support checking specific files in check-templates. 2017-03-19 14:13:38 -07:00
Elliott Jin
357e1a001f refactor: Move check-templates argument parsing to top level. 2017-03-19 14:13:38 -07:00
Elliott Jin
0d677042e7 tools: Remove assert in template linter.
Currently, in the case where `--modified` is not passed, the linter asserts
that it's checking at least 10 files.  Removing this (somewhat arbitrary)
check makes it easier to:

- Add support for specifying files to check via command line arguments
- Reason about cases where `check-templates` is called from `lint-all`
2017-03-19 14:13:38 -07:00
wangjames
12eeb27442 js dependencies: Extract ui_state.js.
The function home_tab_obscured used to be in the ui_state
namespace via a shim, but now we have an actual module for
it.
2017-03-19 14:11:50 -07:00
Sarah Stringer
aa880b0419 Add organization description field to realm settings.
This adds an organization description field to the Realm model, as well as
an input field to the organization settings template. Added three tests.
Set the max length of the field to 100 characters.

Fixes #3962.
2017-03-19 14:05:01 -07:00
Daw-Ran Liou
81f9de7cc8 Add "*" hotkey to toggle starred flag on the selected message. 2017-03-19 13:42:11 -07:00
Brock Whittaker
24e2f31d3d Remove second background from #lighbox_overlay.
The child ".image-preview" has a background which is ordinarily
invisible (as it is the same color as the #lightbox_overlay bg,
however when fading in it is noticeable.
2017-03-19 12:43:10 -07:00
Joshua Pan
234e8b500e Add tests for ctrl key functionality. 2017-03-19 12:17:28 -07:00
Joshua Pan
c053f786f7 Add ctrl+[ hotkey.
Fixes #4016.
2017-03-19 12:17:28 -07:00
Joshua Pan
fcbc2e0cb9 Add ctrl key functionality to hotkeys. 2017-03-19 12:17:28 -07:00
Elliott Jin
bdf4b22772 tools: Only lint changed css files in pre-commit hook. 2017-03-19 11:49:19 -07:00
Elliott Jin
ac5b62359a refactor: Use consistent naming for lint functions. 2017-03-19 11:49:19 -07:00
Jacob Hurwitz
0a76a609ec Fix bugs with handling of the empty narrow.
An empty narrow (ie, the home view) can be represented in code as either
`None` or `[]` but we had incorrect handling that failed to fully
properly deal with either case.

(1) In `get_stream_name_from_narrow`, we failed to deal with `None` by
trying to always iterate over `narrow`.
(2) In several other places, we failed to deal with `[]` by explicitly
checking `if narrow is None` or `if narrow is not None`. Changing these
to truthiness checks should work for both the `None` and `[]` cases.
2017-03-19 11:47:03 -07:00
Daw-Ran Liou
f67751d1f0 Add hotkey "l" for opening image in lightbox.
Open the lightbox in the current selected message. Only the first image
shows in the lightbox.
2017-03-19 11:43:21 -07:00
Tim Abbott
e9f1531fc7 hotkey: Remap v hotkey -> P. 2017-03-19 11:41:02 -07:00
Steve Howell
eda046409c Move paging methods into navigate.js. 2017-03-19 11:05:46 -07:00
Steve Howell
d026344b37 Extract js/ui_util.js. 2017-03-19 11:05:45 -07:00
Steve Howell
099f401b9b Move mark_subscribed/mark_unsubscribed to stream_events.js. 2017-03-19 11:05:45 -07:00
Steve Howell
b98cd55ddb Add ui_report shim. 2017-03-19 11:05:44 -07:00
Steve Howell
c67aebf633 Move keep_pointer_in_view() to message_viewport.js. 2017-03-19 10:56:09 -07:00
Steve Howell
1d7d6869c9 Extract stream_events.js 2017-03-19 10:56:09 -07:00
Steve Howell
cfd1e8cbc3 Extract stream_muting.js. 2017-03-19 10:56:09 -07:00
Steve Howell
5b2407bb22 Add ui_state.home_tab_obscured() shim. 2017-03-19 10:56:09 -07:00
Steve Howell
ab34b5ee9f Extract ui_init.js. 2017-03-19 10:56:09 -07:00
Yago González
a5ecb5e5cf docs: Fix minor link formatting. 2017-03-19 09:16:06 -07:00
Akash Kothawale
93a00d9772 docs: Add missing backtick in architecture-overview. 2017-03-19 09:12:14 -07:00
Yago González
30c0023847 docs: Explain Python 2/3 virtualenvs. 2017-03-19 08:56:19 -07:00
Steve Howell
203ced0ee6 minor: Rename var in filter_emojis(). 2017-03-19 06:25:10 -07:00
Steve Howell
6f3f031791 Make visualizer tool scan each file just once.
Rather than having a bunch of regexes to look for, we just
have a single regex for a function call.  And now we process
line by line, which allows us to more easily ignore comments.
2017-03-19 06:25:10 -07:00
Cynthia Lin
037eca4d64 Add Pygments syntax highlighting info to *Message formatting* modal. 2017-03-18 20:48:01 -07:00
Cynthia Lin
8241f7b40b user docs: Update *Format your message using markdown* with Pygments.
Fixes #4081
2017-03-18 20:48:01 -07:00
Rishi Gupta
6ba11785ea js dependencies: Change hashchange_encode to hash_util_encode in zerver.
This function formerly replicated the behavior of hashchange.encode, and now
replicates the behavior of hash_util.encode.
2017-03-18 20:40:34 -07:00
Rishi Gupta
19d8d16126 js dependencies: Split hash_util.js from hashchange.js. 2017-03-18 20:40:34 -07:00
Tim Abbott
767f57ef03 tests: Remove imports of deleted message_ids. 2017-03-18 20:40:34 -07:00
K.Kanakhin
3e397090e1 user-presence: Add client info to aggregated presence status.
Fixes zulip/zulip-android#454.
2017-03-18 20:36:41 -07:00
Tim Abbott
4dbb17db64 test_helpers: Remove unused message_ids function. 2017-03-18 19:22:49 -07:00
Elliott Jin
1138057209 test-backend: Raise zerver/views/registration.py test coverage to 100%. 2017-03-18 18:11:59 -07:00
Elliott Jin
25d9aac016 registration.py: Don't catch exception that can't be thrown.
A previous commit changed a `get` (which can throw `DoesNotExist`) to use an
existing object, but kept the `try` / `except` block:

4bf3ace444

Removing this unused code path allows us to achieve 100% test coverage.
2017-03-18 18:11:59 -07:00
Elliott Jin
8cfc231d03 tests: Raise zerver/views/registration.py test coverage (part 2). 2017-03-18 18:11:59 -07:00
Jacob Hurwitz
8ab88f5aad Remove hack for old mobile clients
This FIXME was added in 50d229fe11.
Considering it's been more than 4 years, we can probably safely remove
it now.
2017-03-18 18:11:17 -07:00
Jonathan Pan
ceffe2128d activity: Clear search box after clicking a user in right sidebar.
Fixes #4105.
2017-03-18 16:15:14 -07:00
Susan Salituro
a2689d6952 message.py: Delete unused function. 2017-03-18 16:08:36 -07:00
Steve Howell
16a37754cf Add recipient() and composing() shims. 2017-03-18 15:52:50 -07:00
Steve Howell
27f37e6378 Add hash_util.encodeHashComponent() shim. 2017-03-18 15:52:50 -07:00
Steve Howell
d75efa19db Add compose_state.has_message_content() shim. 2017-03-18 15:52:50 -07:00
Steve Howell
59fd9e4d48 Add compose_actions.cancel() shim. 2017-03-18 15:52:50 -07:00
Steve Howell
faa9446e64 Add compose_actions.start() shim. 2017-03-18 15:52:50 -07:00
Steve Howell
35d38d62f3 Add shim.js w/narrow_state global. 2017-03-18 15:52:50 -07:00
Luke W Faraone
68e7a8a824 Show stream properties on subscription in Zephyr.
On realms with ``should_list_all_streams() == False``, previously, we
would subscribe a user to a stream, but also incorrectly show the stream
creation dialog.

Instead, we act as if the stream was newly created.
2017-03-18 15:51:27 -07:00
Elliott Jin
fde1aa506b tests: Prevent misuse of assert_in_success_response.
Changing assert_in_success_response to require List[Text] instead of
Iterable[Text] prevents the following misuse:

    self.assert_in_response_success("message", response)

Currently, this will check whether 'm', 'e', 's', 'a', and 'g' separately
appear in the response, which is probably not the intended behavior.  The
correct usage is as follows:

    self.assert_in_response_success(["message"], response)
2017-03-18 15:49:35 -07:00
Susan Salituro
a2d948f2e0 test_messages: Add test for invalid markdown format. 2017-03-18 14:35:53 -07:00
Jeremy Philemon
9e47ec2270 Made the development environment login page nicer.
- The buttons now have a flat look (dropped the border-radius) with a
white background color.
- The font colors now match the darker green shade of the navbar.
- The border-colors match the lighter green shade of the navbar.
- Green is used for all the normal user buttons, while the admin
buttons are a nice blue.
- I’ve `git grep`d to confirm that changes in .btn-direct only affect
the buttons on login.html

Fixes part of #4106.
2017-03-18 14:31:19 -07:00
Tim Abbott
f67e9a7e5e CSS: Rename #overlay to #lightbox_overlay. 2017-03-18 13:54:11 -07:00
Tim Abbott
ed90879602 js: Extract lightbox.js from ui.js. 2017-03-18 13:54:11 -07:00
Steve Howell
a51caceea5 refactor: Extract unread_ops.js
This module mostly contains the mark_* functions that
update the server with info about unread counts.
2017-03-18 10:35:52 -07:00
Steve Howell
0c6fefba71 Move get_cleaned_pm_recipients() to helper module.
This break's typeahead_helper's dependency on
composebox_typeahead.
2017-03-18 10:35:52 -07:00
Steve Howell
7f43c0504b refactor: Rename fields for split_by_subscribers().
The old name 'subs' was confusing our tooling, since we have
a module called subs.js.
2017-03-18 10:35:52 -07:00
Steve Howell
7b1bfd6703 Break typeahead_helper's dependency on compose.js.
We now have typeahead_helper's callers pass in compose.stream()
when it's needed for sorting purposes.
2017-03-18 10:35:52 -07:00
Steve Howell
166f149ef9 refactor: Add current_stream parameter to functions.
This change makes our dependency on compose.stream_name() happen
in sort_recipients, so we compute it only once, and we can
more easily break the circular dependency.
2017-03-18 10:35:52 -07:00
Jeremy Philemon
f6d01c8232 CSS: Make registration form responsive on <495px screen width. 2017-03-18 08:15:28 -07:00
Jeremy Philemon
f68529e56c Add exit class to the cancel button in invite_user.html.
- Previously, in the invite users modal, the click event of Cancel
(button) triggered the submit-invitation event. (Naturally, if the form
is empty, this throws the validators and doesn’t exit the modal).
- This fixes the abnormal action by including the ‘exit’ class to the
cancel button in invite_user.html, line 36.
2017-03-18 08:12:57 -07:00
adnrs96
d172ea66c6 Clean pygments.css to use 4 space indents. 2017-03-18 08:06:19 -07:00
adnrs96
99616221db Clean portico.css to use 4 space indents. 2017-03-18 07:58:10 -07:00
adnrs96
134e8971aa Clean settings.css to use 4 space indents. 2017-03-18 07:58:10 -07:00
adnrs96
d78495a328 Clean left-sidebar.css to use 4 space indents. 2017-03-18 07:56:08 -07:00
dattatreya303
a61ff3e234 Prevent missed-message emails for deleted messages.
This of course only works in the 2 minute window where missed-message
emails are planned, but nonetheless likely avoids common cases of
emailing users with deleted messages.

Fixes: #3873.
2017-03-18 07:51:32 -07:00
Rishi Gupta
ceac6d9c59 analytics: Remove stray comment from test_counts.py.
The "actual test that would be nice to do" was indeed done!
2017-03-17 21:58:51 -07:00
Umair Khan
645d7c295c Timezone should default to empty string.
Related to #1506
2017-03-17 21:57:16 -07:00
Raghav Jajodia
668d9cc6ca server_events: update admin bots on deactivate under settings tab.
Deactivating a bot in the /#settings/your-bots page update
the /#administration version to show a reactivate button.
2017-03-17 21:11:42 -07:00
Raghav Jajodia
89a83f6a5d admin.js: Refactor code to change view on bot deactivate/reactivate.
This also fixes the error associated with view on toggle deactivation.
Now, on deactivating a bot, the bot-name and bot-email should strike-out.
And on reactivating a bot, the bot-name and bot-email should remove strike-out.
Toggle edit button on bot activation/deactivation.
Fixes #3413.
2017-03-17 21:11:42 -07:00
Tim Abbott
ecea8c2d43 run-dev: Fix missing type annotation. 2017-03-17 21:03:35 -07:00
Steve Howell
623a486c5c tools: Extract is_exterior_node(). 2017-03-17 20:53:27 -07:00
Steve Howell
758ff2e756 Exclude more nodes/edges from our JS visualization.
This also provides a roadmap for how to break some dependencies.
2017-03-17 20:53:02 -07:00
Arpith Siromoney
e073220e21 Add typing notifications front end.
Send typing notification events when user types in the compose box.
Listen for these events and display a notification.

Sending notifications: Notifications are throttled, so that start
notifications are sent every 10 seconds of active typing, and stop
notifications are sent 5 seconds after active typing stops or when the
compose box is closed.

Displaying notifications:
When a typing notification is received, if the current narrow is private
messages or is: pm-with and the user is not the sender,
"Othello is typing..." is displayed underneath the last message. This notification is
removed after 15 seconds. If another notification is received during this period, the
expiration is extended. When a stop notification is received the notification is removed.

Internally, a list of users currently typing is maintained for each
conversation (in a dict). When an event is received the list (for the appropriate
conversation) is updated and the notifications template is re-rendered
based on the narrow information. This template is also re-rendered when
the narrow changes.

Significantly modified by tabbott for clarity.

Fixes #150.
2017-03-17 20:45:07 -07:00
Tim Abbott
25488b550f casper: Fix issues with server autoreloading on save.
This fixes an issue where if you saved a Python file (even just
changing whitespace) while casper tests were running, the Tornado
server being used would restart, triggering a confusing error like
this:

ReferenceError: Can't find variable: $
Traceback:
  undefined:2
  :4
Suite explicitly interrupted without any message given.
2017-03-17 20:45:07 -07:00
Tim Abbott
af8732fd42 py3: Remove unnecesary use of filter. 2017-03-17 20:30:22 -07:00
Tim Abbott
931630abae casper: Clean up wait logic in drafts tests. 2017-03-17 20:01:47 -07:00
Tim Abbott
614391908b typing: Add apply_event handler for typing notifications.
This fixes a crash in the small race condition when loading a browser
window while someone is starting/stopping typing.
2017-03-17 20:01:12 -07:00
Tommy Ip
da49db0201 Create tools/js-dep-visualizer.py.
This tools lets us view circular dependencies in our JS
code.  It does regex parsing, so it has a few false positives,
but it's an early draft of the tools.  Steve Howell helped
with this commit.
2017-03-17 16:09:21 -07:00
Steve Howell
e04a9d38b5 Add tools/lib/graph.py.
This library helps us produce nice graphs for documentation.
2017-03-17 16:00:50 -07:00
Tim Abbott
8efe4d530d js: check_stream_existence to subs.js.
We want to remove this, but in the meantime, this is a more coherent
place for htis to live than compose.js.
2017-03-17 15:16:11 -07:00
Tim Abbott
af5852a55b subs: Eliminate confusing use of settings local.
The name was never good, and was suggestive of the settings module.
2017-03-17 15:07:49 -07:00
Amala Deshmukh
e1624fae0b settings: Explain that users can spell their name how they like.
Fixes #2944.
2017-03-17 14:53:20 -07:00
Amala Deshmukh
0398ec7f81 register: Advertise Zulip's unicode support in registration. 2017-03-17 14:53:20 -07:00
Tim Abbott
497b24d7a6 lint: Ban use of i18n.t in portico js. 2017-03-17 14:14:54 -07:00
Tim Abbott
871adc01e3 signup: Fix broken password strength checking.
We don't support using the i18n libraries in our portico.

This was broken in 7a6d001592.
2017-03-17 14:11:44 -07:00
Umair Khan
4442703011 jinja2: No need for custom render_to_response.
Django 1.10 has changed the implementation of this function to
match our custom implementation; in addition to this, we prefer
render().

Fixes #1914 via #4093.
2017-03-17 13:57:34 -07:00
Umair Khan
d4ee102a95 users: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
62a580a37f unsubscribe: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
446c06bbf4 registration: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
58b407e2ff integrations: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
097b0e3979 home: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
4e2311544f auth: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
97639e5e48 middleware: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
da012ee51b confirmation: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
6511f929cc analytics: Change render_to_response to render.
Related to #4093
2017-03-17 13:52:59 -07:00
Umair Khan
14c2b40acc unsubscribe.py: Pass request to process_subscribe.
We are changing render_to_respone to render; render takes
request as an argument.
2017-03-17 13:52:59 -07:00
Yago González
5516c97a02 frontend: Fix translation string. 2017-03-17 13:42:10 -07:00
inytar
b4e98a695d Set the default locale to en_US.UTF-8 in vagrant.
Prevents errors on vagrant ssh if the host system has an locale unknown
to the vagrant system.
2017-03-17 13:40:41 -07:00
Yago González
eb3304bf37 bots: Move Google search bot and fix bugs.
Now this bot follows our latest structure for contrib_bots.

Switched the dependencies instructions, to install "google" rather than
"google-api-python-client".

Added all the search terms to the query (not only the first one).
2017-03-17 13:03:06 -07:00
sonali0901
49c2472006 docs: Document use of vagrant provision to troubleshoot.
Also documents `provision.log` a bit more.

Tweaked and moved around significantly by tabbott.

Fixes #1886.
2017-03-17 12:58:46 -07:00
Akash Kothawale
9e45f32275 gogs: Add webhook integration.
- Add push, create and pull request event.
- Handle 'opened', 'closed' and 'merged' in 'pull request' event.
- Include tests for all the above events including 'push' with commits
  more than limits.
2017-03-17 12:22:06 -07:00
Akash Kothawale
9c5f1d2239 git.py: Add create branch event message. 2017-03-17 12:22:06 -07:00
Steve Howell
acef337c28 bug fix: Fix update-one-user regression in compose fading.
We now correctly pass the list item for a user to the function
compose_fade.update_one_row().

This regression started happening in the recent commit of
eece725073.  Before that commit,
compose-fade was broken in a different way.

Testing this fix requires creating a stream and opening the compose
box in one window.  Then, in the other window, have a user not
subscribed to the stream log on for the first time.  Be careful
to make sure you flip back to the other browser tab quickly, and
you should see the new user grayed out.  (You can get a false
positive if you wait too long, because the periodic update was
correctly fading before this fix.)
2017-03-17 12:16:48 -07:00
Steve Howell
89e17e1aee refactor: Extract activity.get_user_list_item(). 2017-03-17 12:16:48 -07:00
Tim Abbott
a32dc12a4f lint: Fix PEP8 lint error in googlesearch.py. 2017-03-17 12:15:43 -07:00
royabouhamad
5aff3c7bf6 interactive bots: create a google bot. 2017-03-17 11:54:21 -07:00
Akash Kothawale
edfb9c21bc github_webhook: Send test message sent by GitHub webhook integration.
Fixes #3994.
2017-03-17 11:47:04 -07:00
Akash Kothawale
282d27a934 git.py: Add setup webhook message. 2017-03-17 11:44:01 -07:00
adnrs96
ae200cbaba Clean subscriptions.css to use 4 space indents. 2017-03-17 11:00:44 -07:00
adnrs96
be405200d0 Clean right-sidebar.css to use 4 space indents. 2017-03-17 11:00:44 -07:00
adnrs96
c67eb54d05 Clean media.css to use 4 space indents. 2017-03-17 11:00:44 -07:00
adnrs96
a53114a49a Clean compose.css to use 4 space indents. 2017-03-17 17:07:55 +05:30
Brock Whittaker
d17a3531b3 Fix ui.home_tab_obscured call to not block scroll events.
This fixes the a call being made in ui.js that prevents all scroll
events from occurring while a modal is displayed.

This used to be necessary back in 2012 as modals didn't require
scrolling and would affect background scrolling, however it isn't
required anymore.
2017-03-16 14:23:34 -07:00
Steve Howell
eece725073 compose fade: Limit user-fade to .user-sidebar-entry.
Our JS/CSS now only uses the user-fade class for elements
that have the user-sidebar-entry class.  This should prevent
bugs related to having doubly opaque elements.
2017-03-16 14:06:40 -07:00
Steve Howell
19729b83f4 compose fade: Introduce message-fade/user-fade CSS classes.
We now have specific HTML/CSS classes for message fading and
user fading.  They currently both have the same effect, changing
opacity, but we can now more easily treat them differently.

This change also removes "faded" attributes in compose-fade,
which avoids some confusion related to landing pages having
a "faded" class as well.
2017-03-16 14:06:40 -07:00
Steve Howell
cfba72e59c compose fade: Remove obsolete "unfaded" class.
We don't have any CSS for "unfaded," so setting the class in JS
just slows down the app.
2017-03-16 14:06:40 -07:00
Steve Howell
11e52f5e91 compose fade: Simplify selector for unfading.
We don't set "faded" for ".message_row", so there is no need
to remove the HTML class.
2017-03-16 14:06:40 -07:00
Philip Skomorokhov
8c52a94692 edit: Remove More/Collapse when in message edit/view source mode.
This entails displaying it when the editing mode ends.

Fixes #3871.
2017-03-16 11:30:49 -07:00
wizsid11
19d1f4cab7 git integration: Change push commits message to show url at the end. 2017-03-16 11:06:03 -07:00
zerocod3r
81989b965e Add titles to various message actions elements.
Fixes #4038.
2017-03-16 10:45:05 -07:00
Rohitt Vashishtha
202389d4a7 notifications: Fix incorrect advertising in missed-message emails.
Missed-message email replies using the reply-to of
noreply@zulipchat.com shouldn't advertise that "just replying" will
work.

Rebased and commit message rewritten by tabbott.

Fixes #3965.
2017-03-15 22:34:31 -07:00
Tim Abbott
1c5e9ae7f6 mypy: Fix unicode error in Jira webhook. 2017-03-15 22:01:04 -07:00
Tim Abbott
5db3f60c7d travis: Temporarily disable failing Nagios tests.
Apparently Travis CI has a very strange issue today that causes our
Nagios/E2E tests to have Tornado failing to connect to RabbitMQ.
Causes unknown, but I've spent a day trying to debug this without
luck, and we need our test suites passing in the meantime.
2017-03-15 22:01:04 -07:00
Cynthia Lin
5a95583527 docs: Update zulipbot guide with new features. 2017-03-15 18:01:23 -07:00
Tomasz Kolek
51b839ac11 jira integration: Add support for unicode chars.
Fixes: #3967
2017-03-15 16:26:57 -07:00
kunall17
5a1e952cb5 Implemented test's for muting/unmuting a topic 2017-03-15 16:19:00 -07:00
kunall17
a908bb1898 Implemented API routes for muting/unmuting a topic 2017-03-15 16:19:00 -07:00
Brock Whittaker
966e161fb2 Fix ui.home_tab_obscured to detect modals open.
All open modals now should have the selector ".overlay.show",
so checking if a modal is open is as simple as checking the length
of the selection ".overlay.show".

Fixes #3655.
2017-03-15 15:45:10 -07:00
Tim Abbott
17c8527856 nagios: Clean up check_send_receive_time arguments. 2017-03-15 12:52:27 -07:00
Tim Abbott
0ff1f3d663 nagios: Error on heartbeat events in check_send_receive_time.
It was probably going to fail anyway if those show up, but this
produces a clearer failure mode.
2017-03-15 12:51:19 -07:00
Tim Abbott
04195e0be6 modals: Add blueslip error reporting for invalid modal.
This should help if we screw up adding an additional modal in the future.
2017-03-15 12:35:23 -07:00
Brock Whittaker
3bc2ed6dc9 Switch "invite users" to new component overlay.
Fixes #4036.
2017-03-15 12:29:09 -07:00
Brock Whittaker
6ddf3abe40 Fix pointer events in #settings overlay form sidebar.
The pointer events for the sidebar were incorrect in the way they
were set such that when the sidebar was off to the right and
hidden it would still attract pointer events.
2017-03-15 12:28:49 -07:00
Brock Whittaker
b0e5aeb313 Consolidate JavaScript modal closing in modals.js.
This consolidates all actions to close modals into modals.js and
triggers the correct cleaning/collapsing function dependent on what the
data-overlay attribute is labeled as.

It also ensures these all have an e.stopPropagation().

Fixes #4029.
2017-03-15 12:27:44 -07:00
Brock Whittaker
8ef20a0ed2 Remove meta.focusing boolean.
This was supposed to prevent unwanted modal closes but due to the new
mechanics of modals, it’s better to not prevent the first click.
2017-03-15 12:17:27 -07:00
Brock Whittaker
2e30cef8e9 Change "hashchange.exit_settings" to "hashchange.exit_modal".
Change the name of the hashignore and replace mechanism from
exit_settings to exit_modals since it is now used for more than just
the settings.
2017-03-15 12:17:27 -07:00
Brock Whittaker
075b7cd630 Switch "streams" to new component overlay. 2017-03-15 12:17:27 -07:00
Brock Whittaker
b1839268cd Switch "settings" to new component overlay. 2017-03-15 12:17:27 -07:00
Brock Whittaker
21525ee4db Switch "informational overlays" to new component overlay. 2017-03-15 12:17:27 -07:00
Brock Whittaker
8419eedcbd Switch "lightbox" to new component overlay. 2017-03-15 12:17:27 -07:00
Brock Whittaker
81b2114d8c Switch "drafts" to new component overlay. 2017-03-15 12:17:27 -07:00
Brock Whittaker
c324cdf6cb Add component overlay classes.
These are the classes that should apply to all overlays and replace
their current functions.
2017-03-15 12:17:27 -07:00
K.Kanakhin
f77c5fc086 settings: Extend DATA_UPLOAD_MAX_MEMORY_SIZE from default value.
- In django 1.10 was added `DATA_UPLOAD_MAX_MEMORY_SIZE` parameter,
  which controls max size of uploading files. By default it is 2.5MB.
2017-03-15 12:15:27 -07:00
Rishi Gupta
40fb6ea80e lint: Prevent importing from zerver in migrations. 2017-03-15 12:02:24 -07:00
aakash-cr7
f44caaf36e Focus on the close button when viewing the edit message history.
Fixes #4035.
2017-03-15 11:43:50 -07:00
Cynthia Lin
f47d7b7290 user docs: Update docs to replace *Custom alert words* with *Alert words*.
Fixes #4066
2017-03-15 11:25:37 -07:00
Cynthia Lin
589551b6ee settings: Change "Custom alert words" to "Alert words". 2017-03-15 11:25:37 -07:00
Umair Khan
242d3ffaf4 Add timezone field in UserProfile.
Implements backend of #1506.
2017-03-15 11:18:24 -07:00
Umair Khan
0d296afa54 github: Return '' when name is None. 2017-03-15 11:11:09 -07:00
Umair Khan
e44e58f6d5 logging: Skip log records originated in site packages.
This fixes the huge exception we get in our logs from django.template
logger. This exception is a known bug in Django, see
https://code.djangoproject.com/ticket/26886

Fixes #3974
2017-03-15 11:07:31 -07:00
Cynthia Lin
902207da71 node: Update package.json to eliminate vulnerable dependecies. 2017-03-14 18:21:00 -07:00
Brock Whittaker
c155577246 Allow users to resize the message compose box.
This allows for users to resize the message compose box without it
collapsing back down to jQuery autosize’s preferred height.

When you hide the compose box and then re-show it, it keeps the
previous height but reactivates the jQuery module.

Fixes: #2236.
2017-03-14 17:40:21 -07:00
Rishi Gupta
af4718c50c retention.py: Remove use of domain from get_expired_messages.
get_expired_messages seems to only be used by tests anyway.
2017-03-14 17:17:42 -07:00
Rishi Gupta
92dd767519 management commands: Change help text to say realm instead of domain. 2017-03-14 17:17:42 -07:00
Rishi Gupta
0c032adbde create_realm.py: Remove --domain option.
Realm domains can now be managed via Admin Settings in the web app.
2017-03-14 17:17:42 -07:00
Rishi Gupta
4627ff1b4b zproject: Change comments to refer to Realm.string_id instead of domain. 2017-03-14 17:17:42 -07:00
Rishi Gupta
ba228b75b1 zilencer: Use Realm.string_id for get_deployment_from_domain.
This is dead code. Getting rid of realm__domain since we're about to remove
that field from Realm.
2017-03-14 17:17:42 -07:00
Rishi Gupta
8fecd454aa forms.py: Remove unused function get_registration_string(domain). 2017-03-14 17:17:42 -07:00
Rishi Gupta
ddd0b854f9 Remove references to page_params.domain.
Continuation of 098797c, which removed the page_params.domain field.
2017-03-14 17:17:42 -07:00
Tim Abbott
e7b3ea8fab coverage: Require 100% coverage in analytics. 2017-03-14 17:11:25 -07:00
Tim Abbott
85fe53f5e3 coverage: Don't require test coverage for __unicode__ methods.
These are usually just used for manual debugging, and so aren't super
important to make sure we have tests for always.
2017-03-14 17:07:18 -07:00
Rishi Gupta
7c6f0033ed analytics: Add test for do_drop_all_analytics_tables. 2017-03-14 16:59:54 -07:00
Rishi Gupta
87981a2bf1 analytics: Fix direct import of models in migrations. 2017-03-14 16:59:54 -07:00
Rishi Gupta
ebebd04587 analytics: Fix ValueErrors affecting test coverage.
Pathways that only catch internal code errors should use AssertionError so
that they are not included when computing test coverage.
2017-03-14 16:59:54 -07:00
Rishi Gupta
b18bfe6771 analytics: Standardize format of zerver count queries.
count_message_type_by_user_query is in a different format (no WHERE clause)
from the rest since I'm having a hard time reasoning about how that would
interact with the LEFT JOIN, especially given that there are %(join_args)s.
2017-03-14 16:59:54 -07:00
Rishi Gupta
e33ef1c788 analytics/models: Remove extended_id and key_model.
They are unused / were part of a previous design.
2017-03-14 16:59:54 -07:00
Steve Howell
b648c06009 hotkeys/refactor: Extract tab key handlers.
This extracts process_tab_key() and process_shift_tab_key().
It also removes some dead code related to alert words tabbing.
2017-03-14 16:42:40 -07:00
Steve Howell
bdbaa5d386 hotkeys: Simplify navigation checks for page up/down.
We remove an unnecessary conditional that always returned true
due to checks that happen earlier in the function.
2017-03-14 16:42:40 -07:00
Steve Howell
58c057a024 node tests: Add test_motion_keys(). 2017-03-14 16:42:40 -07:00
Steve Howell
2a3e74427b Export hotkey.tab_up_down() for testing. 2017-03-14 16:42:40 -07:00
Cynthia Lin
7a804de485 user docs: Update *Send a private message*.
Add keyboard shortcut info to user doc. Fixes #156
2017-03-14 15:54:20 -07:00
Cynthia Lin
d764f0e0f1 user docs: Update *Send a stream message*.
Add keyboard shortcut info to user doc.
2017-03-14 15:54:20 -07:00
Cynthia Lin
6deee116dc user docs: Update *Enable or disable pressing enter to send*.
Add keyboard shortcut info to user doc.
2017-03-14 15:54:20 -07:00
Cynthia Lin
f510ada67a templates: Add insert new line shortcut to *Keyboard shortcuts* modal. 2017-03-14 15:54:20 -07:00
Tim Abbott
87dd0c225a keyboard_shortcuts: Move @ near more similar keys. 2017-03-14 15:54:03 -07:00
Abhishek Bhattacharya
8a408a6cbc popovers: Fix actions popover menu positioning.
The main issue is that it wasn't doing the correct comparison; the old
logic that subtracted the viewport.scrollTop() was incorrect for how
our popovers seem to work.

Partially fixes #3741.
2017-03-14 15:37:37 -07:00
Philip Skomorokhov
e3fa42f833 edit: Hide emoji reactions when in message edit or view source mode.
This also entails displaying them when the editing mode ends.

Fixes #3870.
2017-03-14 14:55:16 -07:00
adnrs96
dd52291fa5 linter: Add support for automatic checking for 4 space indents in HTML. 2017-03-14 14:50:16 -07:00
Brock Whittaker
11c7bb49d4 Restyle "invite" modal.
This restyles the invite modal to have the same header as the rest of
the overlays.
2017-03-14 14:47:12 -07:00
Brock Whittaker
4c4208ac86 Make all modal exit "x" sizes uniform.
This makes all exit “x”’s uniformly 1.5rem in size and font-weight: 600.
2017-03-14 14:47:12 -07:00
Raghav Jajodia
b0e2c4ffee settings: refactor code to hide "Email Change" button.
Previously, the code to hide "Change email" button on page load when
email changes are disabled was present in settings.js using jquery to
hide the button. Now, the show/hide is handled in the account-settings handlebars.
2017-03-14 14:43:35 -07:00
Tim Abbott
1b2cbb0b85 casper: Fix incorrect wait condition for realm icons.
This wait condition was correct for uploading, but not for deleting.
2017-03-14 14:40:52 -07:00
Tim Abbott
1c2f82f7fd help: Remove now-unnecessary warning about old messages. 2017-03-14 14:10:08 -07:00
Raghav Jajodia
d21f446083 help: Add user docs for "Prevent change of name" settings. 2017-03-14 14:10:08 -07:00
Raghav Jajodia
ef7e15ee00 admin: Add realm option to prevent users from changing their name.
A realm option to prevent users from changing their name is added.
Fixes #3950.
2017-03-14 14:10:08 -07:00
Raghav Jajodia
dc48b87765 home.py: Fix bug associated with email_changes_disabled.
On reloading the page after disabling email changes does not check
the "Prevent users from changing their email address".
Adding realm_email_changes_disabled to page_params_core_fields fixes the problem.
2017-03-14 14:10:08 -07:00
Abhijeet Kaur
c921736db2 contrib bots: Better error handling response in thesaurus. 2017-03-14 13:29:19 -07:00
Abhijeet Kaur
36bbad3c14 contrib bots: john bot can reply back in the same chat.
No need to create an extra "VirtualHelp" stream.
2017-03-14 13:29:19 -07:00
Abhijeet Kaur
d90906c521 contrib bots: Edit code for uniformity.
Add one function (get_bot_botname_response()) that generates response
from the given input and replies back to the handle_message with the final
content of response to be sent. Also add code to bots(except followup) to
reply to private messages along with stream messages.
2017-03-14 13:29:19 -07:00
Abhijeet Kaur
57d026f4c9 contrib bots: Rename bots to follow a consistent pattern.
Files renamed with few changes to accomodate the change in
path name of files. Fix few "at-mention bot" errors in docs.
2017-03-14 13:29:19 -07:00
Abhijeet Kaur
6e28bc20c6 contrib bots: Rename bots to follow a consistent pattern.
Files renamed without any changes.
2017-03-14 13:29:19 -07:00
Abhijeet Kaur
1a23b218e0 contrib-bots: Update .gitignore to ignore database file. 2017-03-14 13:29:19 -07:00
wizsid11
f066e3e8d6 git integrations: Change the limit of shown commits from 10 to 20. 2017-03-14 13:24:45 -07:00
Umair Khan
cdb07c7005 Fix test_get_old_messages_with_narrow_pm_with.
Fixes #3940.
2017-03-14 09:38:24 -07:00
Umair Khan
7b1742fdef send_message: Allow message to be sent to a huddle. 2017-03-14 09:35:08 -07:00
Steve Howell
1e5ec689b7 tools/css: Trim whitespace around CSS values. 2017-03-14 09:29:56 -07:00
Steve Howell
2ffea94bd8 tools/css: Require semicolons after CSS declarations. 2017-03-14 09:29:56 -07:00
Tim Abbott
a1d7e1b5f6 css: Tweak padding around code blocks to look nicer.
It makes sense to a bit tighter padding around code blocks in a chat context.
2017-03-13 22:35:00 -07:00
Brock Whittaker
a9db9eb389 css: Improve code block styling.
Change pygments for prettier syntax highlighting with white
backgrounds for both inline and multi-line code blocks.
2017-03-13 22:34:11 -07:00
Harshit Bansal
c6cf025ee9 node_tests/dispatch.js: Stub blueslip module.
Stub the blueslip module to print a nicely formatted traceback.
Earlier the traceback used to be only a `ReferenceError` because
blueslip was not stubbed.

Fixes: #4021.
2017-03-13 22:20:59 -07:00
Maxim Averin
b13b660709 zerver: Replace log_event with RealmAuditLog in do_change_user_email.
This replaces the ancient file logging approach for the auditable
password change event with the database audit log.
2017-03-13 22:08:12 -07:00
Maxim Averin
fc35982b87 zerver: Replace log_event with RealmAuditLog in do_change_password.
This replaces the ancient file logging approach for the auditable
password change event with the database audit log.
2017-03-13 22:07:14 -07:00
Elliott Jin
dae5366949 tests: Raise zerver/views/registration.py test coverage. 2017-03-13 21:59:04 -07:00
Elliott Jin
11ad666397 tests: Fix docstring for test_signup_invalid_name. 2017-03-13 21:59:04 -07:00
Steve Howell
a1b5f91c1a hotkeys: Remove wasteful resize calls for keydown events.
This fix prevents us from calling the resize library for nearly
every single keydown event in the app (ouch!).  Realistically,
this performance improvement only impacts folks who turned on
the autoscroll_forever feature, but it should be a significant
speed-up for them.  We should go further with this fix, but the
main damage is undone.
2017-03-13 21:38:23 -07:00
Steve Howell
c88c69db2e bug fixes: Clean up hotkey mappings.
We simplify hotkey mappings by using different hashes for
keydown and keypress events.  There are browser bugs (iOS, for
example) where keypress events have the wrong keyCode values.
This led us, under iOS, to interpret "!" as "page up."

This fix also helps us disinguish escape from shift-escape.

Brock Whittaker helped on figuring out the keypress/keydown
issues that are addressed in this commit.

Fixes #4019
2017-03-13 21:38:23 -07:00
Brock Whittaker
dfa965717f Fix drafts responsiveness issues.
The drafts container was too skinny on mobiles, so the enforced
max-width of 60% should be ignored in favor of expanding to 90%
of the screen width.

This also fixes an issue where the content does not reach the bottom
of the container due to having too short of a height.

Fixes: #3867.
2017-03-13 21:15:56 -07:00
Steve Howell
b99c190380 Extract hotkeys.process_enter_key(). 2017-03-13 15:09:53 -07:00
Steve Howell
cfcad48e46 bug fix: Blur message edit textboxes when hitting escape.
We have a somewhat janky mechanism for rendering message edits,
and before this fix, we were not unblurring the text boxes when
we closed the message editing session with the escape key, which
made it so that the escape key was unusable.
2017-03-13 15:09:53 -07:00
Steve Howell
f9d26856e8 hotkeys: Remove typeahead logic for escape keys.
We had some ancient logic for typeaheads that was supposed to be
Firefox-specific, but I can't reproduce the code even running under
Firefox, and even if it did, it was returning true instead of false
for a long time, so I suspect the code has been wrong/irrelevant for
a long time.
2017-03-13 15:09:53 -07:00
Steve Howell
55ade83ac2 Extract hotkey.process_escape_key(). 2017-03-13 15:09:53 -07:00
Steve Howell
cc6fc3c41a node tests: Add hotkey.js tests.
The initial version of the tests cover most normal keys, but they
do not cover special keys like enter/tab/escape or arrow keys
or home/end/page-down/page-up yet.
2017-03-13 15:09:53 -07:00
Steve Howell
87a7313143 refactor: Extract compose.reply_with_mention(). 2017-03-13 15:09:53 -07:00
Steve Howell
0979aad226 refactor: Export hotkey.processing_text() for tests. 2017-03-13 15:09:53 -07:00
Steve Howell
1df2dfc6e0 hotkeys refactor: Flip conditional related to popovers.
When checking for hotkeys related to popovers, we avoid making
the external call for keys that won't be important for popovers.
This mostly helps testing.
2017-03-13 15:09:53 -07:00
Steve Howell
b1ef7b2e53 Extract hotkey.is_editing_stream_name(). 2017-03-13 15:09:53 -07:00
Steve Howell
1d6e3124c1 Export hotkey.is_settings_page() for testing. 2017-03-13 15:09:53 -07:00
Steve Howell
db3883fc51 hotkeys: Refactor backspace/shift-tab sections.
Only check to see if the compose send button is in focus if
we dealing with backspace/shift_tab.  As the comment notes here,
these sections of code are somewhat dubious.
2017-03-13 15:09:53 -07:00
Steve Howell
20f26c40e1 Export process_hotkey() for testing. 2017-03-13 15:09:53 -07:00
Steve Howell
ef3033c79e node tests: Make with_overrides() more granular.
The with_overrides() function no longer works at the module
level, so you can temporarily override one function in a module
without breaking more permanent monkey patches.

This makes us slightly more vulnerable to unintentional test
leakages, but it solves the problem where you often need lots
of temporary overrides for writer functions but you want to
keep a more permanent override for some sort of reader function.
2017-03-13 15:09:53 -07:00
Steve Howell
a98999ce27 node tests: Extract with_overrides() helper.
The function with_overrides() uses the logic from the old
run() function in dispatch.js to allow you to call a test
function and override parts of the global namespace only
for the duration of when test_function runs.
2017-03-13 15:09:53 -07:00
Steve Howell
ff9b753acd Use with_stub() in node dispatch tests. 2017-03-13 15:09:53 -07:00
Steve Howell
51c57bb05d node tests: Add with_stub() helper. 2017-03-13 15:09:53 -07:00
Steve Howell
0097bd1d14 minor: Remove redundant call in dispatch test. 2017-03-13 15:09:53 -07:00
Steve Howell
bf8f0059f3 node tests: Change params to override() in dispatch.js.
We now pass in function names as 'foo.bar', which is a bit
easier to type/read/grep, rather than passing the module name
and function name individually.
2017-03-13 15:09:53 -07:00
Cynthia Lin
6fd6ef5d57 user docs: Mention message edit history feature in *Edit or delete a message*. 2017-03-13 15:03:35 -07:00
Cynthia Lin
1f2eddad8b user docs: Add user guide for *View a message's edit history* feature.
Fixes #3730
2017-03-13 15:03:35 -07:00
Cynthia Lin
ccd2e40c3a templates: Change button name in *Message edit history* modal.
Changed from **Cancel** to **Close**.
2017-03-13 15:03:35 -07:00
Cynthia Lin
f15e6f66a4 travis: Enable zulipbot build notifications.
PRs labeled with the *travis updates* label will receive build notifications from zulipbot.
2017-03-13 15:00:51 -07:00
Rishi Gupta
871c754369 bulk_create: Remove unused function bulk_create_realms. 2017-03-13 14:42:55 -07:00
Rishi Gupta
ae76f2540f events.py: Remove realm_domain from fetch_initial_state_data.
Seems unused. git grep from realm_domain returns nothing of relevance.
2017-03-13 14:42:55 -07:00
Rishi Gupta
098797cd36 Remove page_params.domain. 2017-03-13 14:42:55 -07:00
Rishi Gupta
9df26a296f composebox_typeahead.js: Remove unnecessary special case for zulip.com.
This was originally introduced in
025b79d98b, which is far back in ancient
history when compose had a different shape (predates enter-sends,
too), and regardless, this code never affected anything but zulip.com.
2017-03-13 14:36:34 -07:00
Rishi Gupta
7dc7b1653c actions: Remove unnecessary domain in validate_user_access_to_subscribers.
validate_user_access_to_subscribers_helper never uses
stream_dict['realm__domain']. I imagine it was there originally to do the
is_zephyr_mirror_realm check.
2017-03-13 14:28:43 -07:00
Rishi Gupta
b4ac768568 realm_icon: Use string_id instead of domain for Realm gravitar. 2017-03-13 14:28:43 -07:00
Rishi Gupta
3645bb9225 Change if(realm.domain == mit.edu) to use Realm.is_zephyr_mirror_realm. 2017-03-13 14:17:14 -07:00
Rishi Gupta
3aae6cd421 Change if(realm.domain == zulip.com) checks to use Realm.string_id. 2017-03-13 14:17:14 -07:00
Rishi Gupta
128c431f14 cache.py: Change realm_alert_words_cache_key to use Realm.string_id. 2017-03-13 14:17:14 -07:00
Rishi Gupta
a0ca2886ef actions: Change email in do_refer_friend to use Realm.string_id.
This looks unused anyway, since it's sending mail to @zulip.com.
2017-03-13 14:17:14 -07:00
Rishi Gupta
15a8d5acc1 actions: Modify recipient_for_emails to not use Realm.domain.
Realm.domain was just being used as a unique identifier for a Realm.
2017-03-13 14:17:11 -07:00
Rishi Gupta
727fac75c7 signups: Use topic string_id for internal messages from new user signups.
Previously we used the topic "Realm.domain" for new user signups, but topic
"Realm.string_id" for the realm creation. This changes the user signup
messages to be on the same topic thread as the realm creation.
2017-03-13 10:00:41 -07:00
Rishi Gupta
ef532bbbb1 statsd: Change keys to use Realm.string_id instead of domain. 2017-03-13 09:51:02 -07:00
Rishi Gupta
11346e50bb management commands: Use Realm.string_id instead of domain in print statements. 2017-03-13 09:44:32 -07:00
Rishi Gupta
5dc683ba8d Use Realm.string_id instead of Realm.domain when logging. 2017-03-13 09:42:14 -07:00
Rishi Gupta
00f49d4121 views/users.py: Change error message to use Realm.string_id instead of domain. 2017-03-13 09:37:06 -07:00
Rishi Gupta
0559afb928 models: Use Realm.string_id instead of domain in RealmFilter.__unicode__. 2017-03-13 09:27:21 -07:00
Rishi Gupta
cc25193faa models: Use Realm.string_id instead of domain in RealmEmoji.__unicode__. 2017-03-13 09:26:26 -07:00
Rishi Gupta
a2bfa7793a models: Use string_id instead of domain in Realm.__unicode__. 2017-03-13 09:23:07 -07:00
Rishi Gupta
b81c86ffca actions.py: Replace realm.domain with string_id in calls to log_event.
log_event is deprecated and only being used as a reminder for what needs to
be transitioned to RealmAuditLog.
2017-03-12 23:06:57 -07:00
adnrs96
a75c0dd248 Enhance template parser for comments, Fix deep nesting in Jinja2.
In this commit we add the ability of recognizing comments in
handlebar and Jinja2 templates to the template parser. This
fixes issue of template parser picking up code tags which are
commented out in files.
Also we fix the problem of too much deep nesting in the Jinja2
logic statement. Now only nested Jinja2 logic statements will get
a deeper indentation level.With this another fix was introduced
relating with the tags before a nested handlebar or django tag getting
wrong indent.
We also fix the issue with wrong offsets with closing tags in
cases if they were not matching indent level of the starting
tag intially.
Also we also start to ignore any tags occuring in between 'pre'
tags for deeper indent levels. As well we start to filter out django
non block tags from getting deeper indent level.
2017-03-11 15:16:44 -08:00
Tim Abbott
5e39ccd642 js: Rename viewport.js to message_viewport.js.
This fixes the mobile web experience for Chrome on iOS.

Apparently, Chrome-on-iOS silently has a `viewport` module that
overrides and user-defined module by that name, causing all of our
code that accesses the viewport module to not work on that platform.
We fix this by renaming it.
2017-03-10 14:59:59 -08:00
Tim Abbott
b1f12133be build-release-tarball: Error on uncommitted changes. 2017-03-10 11:49:49 -08:00
adnrs96
3d2fc9171f Clean features.html to use 4 space indents. 2017-03-10 11:24:30 -08:00
adnrs96
b33836ed76 Clean subscriptions.html to use 4 space indents. 2017-03-10 11:24:30 -08:00
adnrs96
7e20c96281 Clean right_sidebar.html to use 4 space indents. 2017-03-10 11:24:29 -08:00
Umair Khan
90ee06bd89 capitalization: Make it easier to ignore phrases.
This commit allows us to add the errors shown by the
tools/check-capitalization in the IGNORED_PHRASES list
without any modification.
2017-03-10 11:21:49 -08:00
adnrs96
43b19a6997 Clean user_presence_row.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
adnrs96
ccec320f1d Clean stream_sidebar_actions.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
adnrs96
ebf3eaf9ae Clean stream_member_list_entry.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
adnrs96
d9a0fcc931 Clean tutorial_message.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
adnrs96
e08d28bd0f Clean email_address_hint.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
adnrs96
11418ed9c8 Clean draft_table_body.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
adnrs96
bf577297c7 Clean tab_bar.handlebars to use 4 space indents. 2017-03-10 11:07:49 -08:00
Harshit Bansal
c6681917c1 settings: Add UI to allow a user to reactivate his own bots.
Using this UI, a user can now reactivate the bots owned by him.
Until now if a bot was deactivated, there was no way to use the
old bot's original email address. But now they can be reactivated
and their email can be reused.

Fixes: #1183.
2017-03-10 10:59:49 -08:00
Harshit Bansal
0dbca4a3c3 settings: Display all the bots owned by an user.
Add UI to display all the bots owned by an user whether active
or inactive in "Your Bots" section.
2017-03-10 10:59:49 -08:00
Harshit Bansal
876d7bbcdc settings: Rename bots_list to active_bots_list. 2017-03-10 10:59:49 -08:00
Tim Abbott
900891b072 settings: Rename settings-status to account-settings-status. 2017-03-10 10:53:06 -08:00
Raghav Jajodia
05f0d1953b account-settings: Removed 'Updated settings' message from admin.
The 'Updated Settings' message we get at the bottom
of admin-page when we change the name is removed.
Fixes #3815.
2017-03-10 10:53:06 -08:00
Harshit Bansal
c5ffef28bb tools/check-capitalization: Make error messages more clear. 2017-03-10 10:51:01 -08:00
Kanak Garg
5023b69ca5 stream settings: Add "View Stream" button.
This adds a button to #subsciption page called "View Stream"
that narrows the user to that particular stream.

This fix involves typical changes to JS/CSS to add new features,
and we also add a "preview_url" field to the sub object in
stream_data.js.

Fixes #3878
2017-03-10 08:26:57 -08:00
James Wang
405f07454c Add server version to about page template.
zserver/context_processors.py: Pull in ZULIP_VERSION variable from version.py
about.html: Put server version into template.

Fixes: #3907
2017-03-09 22:10:54 -08:00
Umair Khan
7bc3fa034e linter: Add rule to check periods in translatable.
Make sure that the periods are part of the translatable strings.

Tweaked by tabbott to properly scope the rules.
2017-03-09 21:57:26 -08:00
Umair Khan
b228cca377 linter: Fix periods in translatable strings. 2017-03-09 21:57:24 -08:00
Raghav Jajodia
c17e574211 Remove product_name setting and return to harcoding 'Zulip'.
This removes some confusion in grep for frontend strings with Zulip in
them and also cleans up the code in some places.

Fixes #1602.
2017-03-09 21:48:15 -08:00
Tim Abbott
60296c022c test_messages: Attempt to fix flaky coverage again. 2017-03-09 21:42:22 -08:00
Tim Abbott
c2bee5a89b auth: Fix fetch_auth_backends to properly report supported methods.
This fixes 2 related issues:
* We incorrectly would report authentication methods that are
  supported by a server (but have been disabled for a given
  realm/subdomain) as supported.
* We did not return an error with an invalid subdomain on a valid
  Zulip server.
* We did not return an error when requesting auth backends for the
  homepage if SUBDOMAINS_HOMEPAGE is set.

Comes with complete tests.
2017-03-09 21:37:00 -08:00
Amy Liu
e5ab3123af Migrate json/set_muted_topics to muting/topics. 2017-03-09 20:52:29 -08:00
Amy Liu
9500c88e32 Migrate legacy url json/bulk_invite_users to invite/bulk_invite. 2017-03-09 20:51:03 -08:00
Tim Abbott
4ac5da7860 travis: Run test-tools in Travis CI backend suite. 2017-03-09 20:21:13 -08:00
Tim Abbott
c5cae34512 tools: Fix test-capitalization dependence on Django.
This was a totally unnecessary dependency, and actually broke
test-tools.
2017-03-09 20:21:13 -08:00
Raghav Jajodia
7f5abcef9c subs: Modify css to fix stream description cut off.
Fixes the cut off of Stream descriptions at the bottom of
subscriptions page if they have `g`s in them.
Fixes #3277.
2017-03-09 20:03:35 -08:00
Tim Abbott
ce826e82c5 reactions: Fix click handler for reactions button.
This was broken when we fixed the click target for the other reactions
button place.
2017-03-09 12:18:17 -08:00
Raghav Jajodia
217b8f2a85 hotkeys: escape key press dismiss "invite-users" modal.
Pressing escape key dismiss the invite-user modal.

Fixes #4008.
2017-03-09 12:10:27 -08:00
Saurav Pratihar
9ab4b3b6cc topics: Add tooltip showing full topic name in left sidebar.
This is useful if the topic name is too long and thus is cut off for
display purposes.

Fixes #3979.
2017-03-09 11:12:32 -08:00
adnrs96
621e0749dc Clean subscription_table_body.handlebars to use 4 space indents. 2017-03-09 01:17:25 -08:00
adnrs96
46ea4ea05f Clean subscription_stream_privacy_modal.handlebars to use 4 space indents. 2017-03-09 01:17:25 -08:00
adnrs96
8b164b57ad Clean muted_topic_ui_row.handlebars to use 4 space indents. 2017-03-09 01:17:25 -08:00
adnrs96
25c656a6cc Clean message_reaction.handlebars to use 4 space indents. 2017-03-09 01:17:25 -08:00
adnrs96
33a8aa7bf2 Clean bot_owner_select.handlebars to use 4 space indents. 2017-03-09 01:17:23 -08:00
adnrs96
f5afcb5a4b Clean topic_edit_form handlebar to use 4 space indents. 2017-03-09 01:17:23 -08:00
Rafid Aslam
1143a2d8c4 attachment: Add file icon to the green box when file has no extension.
Fixes #3848.
2017-03-09 00:56:37 -08:00
Umair Khan
32849b80ad Django 1.10: Url pattern doesn't use _callback_str.
Fixes #3941
2017-03-09 00:50:12 -08:00
Umair Khan
83dd901ecf Add capitalization checker tool.
Initial rules significantly by modified by tabbott, who also added the
hacky list of excludes that the tool can't handle correctly yet.

Fixes: #3899.
2017-03-09 00:44:57 -08:00
Tim Abbott
84d4f62abf lint: Exclude Acme placeholders from translations.
These strings represented a small waste of time for our translators.
2017-03-09 00:38:15 -08:00
Tim Abbott
ac20872f9d request: Fix unnecessary translation tag for assertion. 2017-03-09 00:38:14 -08:00
Tim Abbott
aacef438bc confirmation: Remove i18n from confirmation models.
These make sense to be tagged for translation if one is using the
Django admin UI, which we're not.  As it was, they just wasted a bit
of time for our translators.
2017-03-09 00:37:45 -08:00
Tim Abbott
8bdbcbc371 lint: Fix unnecessarily translated test file strings.
Our linter for translation strings shouldn't check test files, since
then we'll end up translating non-user-facing strings.

So we fix that, and actually add the opposite lint rule.
2017-03-09 00:37:44 -08:00
Tim Abbott
cc07190fdc capitalization: Clean up failed message sending options. 2017-03-09 00:36:13 -08:00
Umair Khan
149b0c30df capitalization: Fix Only Basic authentication is supported. 2017-03-08 23:40:57 -08:00
Umair Khan
2894924ffb capitalization: Fix Only Admins may now create new streams. 2017-03-08 23:40:15 -08:00
Umair Khan
c0e92015fd capitalization: Fix Only Admins may now add new emoji. 2017-03-08 23:38:36 -08:00
Umair Khan
3b05937e86 capitalization: Fix API Key in documentation. 2017-03-08 23:36:36 -08:00
Tim Abbott
70aa443c25 stream_popover: Fix references to topic_ops.
This apparently got lost in the refactoring that extracted
stream_popover.js.
2017-03-08 23:30:44 -08:00
Tim Abbott
5613358638 stream_popover: Fix hiding topic popover. 2017-03-08 23:25:30 -08:00
Tim Abbott
ae12f3dfd0 github: Fix URL in GitHub webhook documentation. 2017-03-08 23:25:30 -08:00
Tim Abbott
6a5e98b77e puppet: Increase MaxStartups SSH configuration. 2017-03-08 22:28:16 -08:00
adnrs96
556dde8e3e avatar migration: Handle missing avatars for S3 gracefully.
In this commit we start to handle missing avatars gracefully in case
migration was being run on the AWS.
2017-03-08 22:24:07 -08:00
adnrs96
e43f446b1e Clean portico.html to use 4 space indents. 2017-03-08 22:08:05 -08:00
adnrs96
b7b295f0ad Clean api_endpoints.html to use 4 space indents. 2017-03-08 22:08:01 -08:00
adnrs96
c5abccc9ec Clean accounts_accept_terms.html to use 4 space indents. 2017-03-08 22:08:01 -08:00
Tomasz Kolek
114c80efae Add ignore pull requests mechanism in Travis integration.
Add ignore_pull_requests param to url, with a default of true.

Fixes: #3912.
2017-03-08 21:51:04 -08:00
Tomasz Kolek
15485ec972 Refactor travis integration. 2017-03-08 21:49:32 -08:00
Brock Whittaker
f63f251f8f css: Fix styling and padding in mobile sidebars.
Fixup the styling of the mobile sidebars to be a little bit more
stylistically uniform.
2017-03-08 21:23:29 -08:00
Brock Whittaker
a94077db07 Make subscriptions page scrolling responsive.
This fixes some scrolling issues that are present on mobile and iOS.
2017-03-08 21:08:36 -08:00
Brock Whittaker
db45d220a8 Disable mobile zooming of the Zulip webpage.
This disables the zooming ability of the mobile webpage which is good
as focusing on input will automatically zoom the page and sometimes
break content.
2017-03-08 21:08:04 -08:00
Brock Whittaker
bb13cad60f compose: Bring back the compose buttons on mobile.
Before they were hidden in favor of icons, but now there’s no need to
hide them, we should just display the original buttons.
2017-03-08 21:07:43 -08:00
Tim Abbott
342a80c3de lint: Ban use of datetime.(utc)now in Python backend.
This may be all we're doing for #3999, but leaving it open just in
case.
2017-03-08 21:03:27 -08:00
Brock Whittaker
c5ba4e11d4 Redesign "/integrations/" page in portico.
This redesigns the integrations page to incorporate the new landing nav,
CSS animations, and general styling of the product page set.
2017-03-08 17:42:17 -08:00
Tim Abbott
ac138b6e93 templates: Rename landing-nav.html to landing_nav.html. 2017-03-08 17:30:44 -08:00
Brock Whittaker
30bd61530d Add elastic scrolling to iOS.
This adds elastic scrolling to iOS to allow for scroll inertia
properties as standard webpages should exhibit.
2017-03-08 17:04:10 -08:00
Brock Whittaker
1d2c3cec10 Fix: change mobile sidebar click target to call new popover function.
This changes the click target that opens the mobile sidebar to call the
new popover function in stream_popover rather than the old popovers
object.
2017-03-08 17:04:10 -08:00
Rishi Gupta
76ccf2732c actions.py: Remove date_joined argument to do_activate_user.
All current calls to do_activate_user just use the default value of
timezone.now().  Having a date_joined other than timezone.now() raises an
interesting RealmAuditLog question (namely, which time should be used),
which we don't have to answer if we remove the argument.
2017-03-08 17:03:20 -08:00
Rishi Gupta
36db89c0a5 actions.py: Remove log_event for functions that log to RealmAuditLog. 2017-03-08 17:03:20 -08:00
Tim Abbott
3b59e6c3cc subs: Rename /#subscriptions to /#streams.
Fixes #3653.
2017-03-08 16:57:58 -08:00
Tim Abbott
d420aa72b8 actions: Fix default domain for realm creation.
The old domain was actually an email, not a domain, and hardcoded
acme.com :(.
2017-03-08 16:52:37 -08:00
Rishi Gupta
5cfd1e1266 bot settings: Change placeholder from bot_user_name to cookie. 2017-03-08 16:26:13 -08:00
Rishi Gupta
3797fa657e Change bot domains to string_id.EXTERNAL_HOST.
Change applies to both subdomains and non-subdomains case, though we use
just the EXTERNAL_HOST in the non-subdomains case if there is only 1 realm.

Fixes #3903.
2017-03-08 16:26:13 -08:00
Tim Abbott
4a1f1db9ee users: Avoid inserting into the DOM in a loop.
This fixes a major performance issue loading the administration page
in large organizations.
2017-03-08 16:21:25 -08:00
Tim Abbott
a8d8855624 attachment: Avoid inserting into the DOM in a loop.
This has a huge impact on the performance of loading the settings page
if you have a decent number of past uploaded files.
2017-03-08 16:20:50 -08:00
Tim Abbott
9c02e59b66 hotkey: Fix K/J being treated as hotkeys in compose. 2017-03-08 16:02:33 -08:00
Tim Abbott
e61b54b74a Fix spacebar being broken in the compose box.
This fixes a regression introduced in
8801158dfd.

Apparently the `page_up`/`page_down` hotkey definitions somewhat
confusingly called `spacebar` `page_down`, etc.  Probably worth doing
further cleanup on this.
2017-03-08 15:57:56 -08:00
derAnfaenger
0047dbaa24 Replace native datetimes in the Codebase integration.
Update all utcnow() and now() calls, as well as other native dates to
specify the UTC timezone.
Fixes #3809.
2017-03-08 15:32:06 -08:00
Tim Abbott
fc3927a124 subs: Improve meta.stream_created targeting.
This fixes a potential race where you get subscribed to a stream
around the same time that you create a stream.
2017-03-08 14:47:49 -08:00
Brock Whittaker
022aeca085 subs: Prepend new streams to top of stream list.
This prepends new streams that are created to the top of the list so
that they are more visible when being created.
2017-03-08 14:47:00 -08:00
Brock Whittaker
8801158dfd Add hotkey actions for page up/down in compose box.
The hotkey actions make the caret position go to the top of the compose
box or bottom respectively, while the compose box is open.

Fixes #1910.
2017-03-08 14:13:05 -08:00
Tim Abbott
13e82f1a16 casper: Fix test failure due to recent capitalization change. 2017-03-08 14:10:51 -08:00
Tim Abbott
149ca79a2b node: Fix test failure due to recent capitalization change. 2017-03-08 12:41:21 -08:00
Tim Abbott
ee231c0223 login: Improve development server login copy. 2017-03-08 12:36:04 -08:00
Tim Abbott
b126d64ead api: Fix API Keys capitalization. 2017-03-08 12:33:37 -08:00
Umair Khan
f5a1b5d88f capitalization: Fix Zulip Features. 2017-03-08 12:33:37 -08:00
Umair Khan
4ab06a8645 capitalization: Fix Short Name. 2017-03-08 12:33:37 -08:00
Umair Khan
a7ac0c69ac capitalization: Fix Organization Type. 2017-03-08 12:33:37 -08:00
Umair Khan
194ac99315 capitalization: Fix Log In. 2017-03-08 12:33:37 -08:00
Umair Khan
7f129397a6 capitalization: Fix Bot Email. 2017-03-08 12:33:37 -08:00
Umair Khan
d4228e8151 capitalization: Fix waiting period threshold changed. 2017-03-08 12:33:37 -08:00
Umair Khan
22c1c13f38 capitalization: Fix View Source / Edit Topic. 2017-03-08 12:33:37 -08:00
Umair Khan
935cacfc86 capitalization: Fix View Source. 2017-03-08 12:33:37 -08:00
Umair Khan
523f8ecd79 capitalization: Fix Upload New Avatar. 2017-03-08 12:33:37 -08:00
Umair Khan
3dd823b0af capitalization: Fix Stream Name. 2017-03-08 12:33:36 -08:00
Umair Khan
fdb709d0b7 capitalization: Fix No Drafts. 2017-03-08 12:29:07 -08:00
Umair Khan
9faf73eaa9 capitalization: Fix Generate new API Key. 2017-03-08 12:29:07 -08:00
Umair Khan
569418f0b4 capitalization: Fix Full Bot Name. 2017-03-08 12:29:07 -08:00
Umair Khan
7d398f4ce3 capitalization: Fix Exit Tutorial. 2017-03-08 12:29:07 -08:00
Umair Khan
7420d77cc3 capitalization: Fix Edit User. 2017-03-08 12:29:07 -08:00
Umair Khan
1863ce41f1 capitalization: Fix Delete Avatar. 2017-03-08 12:29:07 -08:00
Umair Khan
a67b405f3b capitalization: Fix Delete Alert Word. 2017-03-08 12:29:07 -08:00
Umair Khan
780e3d8d12 capitalization: Fix Deactivate Account. 2017-03-08 12:29:07 -08:00
Umair Khan
6728d212a6 capitalization: Fix Copy from Stream. 2017-03-08 12:29:07 -08:00
Umair Khan
33325d94ab capitalization: Fix Change Password. 2017-03-08 12:29:07 -08:00
Umair Khan
7973b7ffd2 capitalization: Fix Allow Subdomains. 2017-03-08 12:29:07 -08:00
Umair Khan
0a41c12a07 capitalization: Fix Alert Word. 2017-03-08 12:29:06 -08:00
Umair Khan
0d31bcc2f7 capitalization: Fix API Key. 2017-03-08 12:29:06 -08:00
Tim Abbott
5cc900eca6 README: Rename peer review -> code review. 2017-03-08 11:44:33 -08:00
Elliott Jin
8d936601d3 test-backend: Raise zerver/views/test_upload.py test coverage to 100%. 2017-03-08 11:42:25 -08:00
Tim Abbott
841e81d21e tests: Fix six.moves range import placement. 2017-03-08 11:36:04 -08:00
Steve Howell
a61f468348 Simplify buddy list status level sorting.
Introducing the level function makes it a bit more clear that active
users get sorted to the top.

It also shaves a couple milliseconds for large buddy lists, although
that is mostly negligible compared to name sorting and rendering.
2017-03-08 11:32:23 -08:00
Steve Howell
bdd8964ca9 Simplify and speed up buddy list name sorting.
We remove duplicate calls to people.get_person_from_user_id here.
With 2000 users, this makes the sort about 10ms faster.
2017-03-08 11:32:23 -08:00
Steve Howell
a246d2dcb3 refactor: Eliminate presence_info params.
It's easier to reason about the activity.js code if we just
make it clear that presence_info is a global singleton.  Going
forward, functions that use that data will explicitly refer to
exports.presence_info.

This change makes some tests slightly more awkward to set up, but
with the actual code you now don't have to question whether there
are multiple copies of presence_info to maintain.

The diff for compare_function is a bit confusing to read, but it's
basically just de-dented since we don't need to parameterize the
compare function any more.
2017-03-08 11:32:23 -08:00
Steve Howell
89d362656a Simplify focus_lost() function (and add comments).
The function focus_lost() was setting has_focus to false
in all cases; now it does it more clearly.  I also added a
comment explaining why we don't ping on losing focus.
2017-03-08 11:32:22 -08:00
Steve Howell
7cec88c748 performance: Avoid unnecessary buddy list redraws.
We no longer build the buddy list twice during page load; we
build it just once from page_params information.  (We also send
the initial ping and schedule subsequent pings slightly later in
the process.)

We also don't do redraws upon regaining focus, since we don't
show ourselves in the buddy list, and even if we did, we wouldn't
need a full server update.

To have this flexibility, we introduce the want_redraw flag to
focus_ping.
2017-03-08 11:09:13 -08:00
Tim Abbott
cb14b4405c tests: Rename zerver/tests/tests.py to test_users.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
8675be2daf tests: Move ModelTest to test_presence.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
ff7e3a2125 tests: Move ExtractedRecipientsTest test to test_messages.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
ff598a091c tests: Extract zerver/tests/test_muting.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
352551503c tests: Move UtilsUnitTest test to test_docs.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
c0f43ce343 tests: Move PublicURLTest tests to test_urls.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
a2ebece9b7 tests: Move login-related tests to test_signup.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
94ed405c69 tests: Extract zerver/tests/test_middleware.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
46362dfcca tests: Move AuthorsPageTest to test_docs.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
881169f08a tests: Move DocPageTest to test_docs.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
edbb3fa4ec tests: Rename test_integrations to test_docs. 2017-03-08 03:57:37 -08:00
Tim Abbott
729bcc8b16 tests: Move TestOpenRealms to test_signup.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
e8b08d10f0 tests: Extract zerver/tests/test_notifications.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
eefd5d4cf6 tests: Move UserChangesTest to test_settings.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
3d98b1cdef tests: Extract zerver/tests/test_queue_worker.py. 2017-03-08 03:57:37 -08:00
Tim Abbott
4e34719563 tests: Extract zerver/tests/test_realm.py. 2017-03-08 03:15:16 -08:00
Tim Abbott
b5cca309d6 tests: Extract zerver/tests/test_settings.py. 2017-03-08 03:13:28 -08:00
Tim Abbott
123b4c1877 tests: Extract zerver/tests/test_bots.py. 2017-03-08 03:09:32 -08:00
Tim Abbott
7d9e80599b tests: Extract zerver/tests/test_zephyr.py. 2017-03-08 03:08:30 -08:00
Tim Abbott
c66549dee0 tests: Extract zerver/tests/test_home.py. 2017-03-08 03:00:05 -08:00
Tim Abbott
a55381b397 sessions: Fix missing typing imports. 2017-03-08 03:00:05 -08:00
Tim Abbott
7aa9dc3922 Fix test_templates failure with new landing-nav.html. 2017-03-08 02:53:57 -08:00
Tim Abbott
ca50e10569 sessions: Move session deletion code to sessions.py.
This new organization feels more thematically appropriate, and of
course shrinks the amount of stuff unnecessarily in actions.py
2017-03-08 02:48:18 -08:00
Tim Abbott
fe237118b0 Rename zerver/lib/session_user.py to sessions.py. 2017-03-08 02:43:35 -08:00
Tim Abbott
6dfbdec82c lint: Fix closing tags in api.html. 2017-03-08 01:16:08 -08:00
Tim Abbott
84eb427c63 lint: Fix settings.py linewrapping. 2017-03-08 01:15:24 -08:00
Rohitt Vashishtha
6e238c9235 docs: Update API docs to include complete list of supported Env Vars. 2017-03-08 01:02:33 -08:00
Rohitt Vashishtha
fc41a37db3 docs: Update API docs to include Environment Variables details. 2017-03-08 01:02:33 -08:00
Brock Whittaker
3b55519b11 Redesign "/features/" page in portico.
This redesigns the features page to incorporate the new landing nav,
CSS animations, and general styling of the product page set.
2017-03-07 23:25:39 -08:00
Tim Abbott
7c9ee2f677 avatar migration: Remove now-unnecessary debugging print. 2017-03-07 23:17:11 -08:00
Tim Abbott
a32f666f5c avatar migration: Handle missing avatars gracefully.
This makes the outcome if a user didn't have an avatar due to a past
email change reasonable; the user will just be bumped back to
gravatar, fixing their invalid state.
2017-03-07 23:10:15 -08:00
Tim Abbott
0afd4d5740 avatar: Add error handling for avatar migraton. 2017-03-07 23:10:15 -08:00
adnrs96
ae31c6cc0d avatar: Move avatar data from email based to user id based.
This commit introduces a migration for moving avatars from email based
to user id based storage.

This is in responce to change in behaviour of user_avatar_path to
return path comprising of realm id and a hash based on user id. Also
we fix test_helpers accordingly.

Fixes #3776.
2017-03-07 22:44:26 -08:00
Raghav Jajodia
21f0339cfc compose: Focus on topic when narrowed to a stream+topic.
When narrowed to a stream+topic and clicking the "new topic" button,
focus in on topic and the text remains selected.
Fixes #3888.
2017-03-07 22:24:57 -08:00
Abhijeet Kaur
b8341280e8 doc updates: Remove triage_message function from contrib-bots. 2017-03-07 22:23:11 -08:00
K.Kanakhin
1cb0f8dc41 Add size limit for uploading user avatars and realm icons.
- Add settings parameter for max realm icon size.
- Add settings parameter for max user avatar size.
- Add checking file size to avatar and icon
  uploading views.
- Transfer file size limit parameter to frontend.
- Add tests.
2017-03-07 22:13:01 -08:00
Tim Abbott
01129c1ab9 home: Simplify logic for realm_icon_source/url. 2017-03-07 22:09:58 -08:00
K.Kanakhin
72424f3a9f realm-icon: Fix variable name for realm icon source. 2017-03-07 22:09:58 -08:00
Vasu Verma
d4a004c420 Fix enter key not deleting selected text in compose box.
Fix #3889.
2017-03-07 22:04:04 -08:00
Feorlen
e0acdfde0d Add a Splunk webhook integration.
Add a webhook to create messages from Splunk search alerts. The search
alert JSON includes the first search result and a link to view the full
results. The following fields are used:

* search_name - the name of the saved search
* results_link - URL of the full search results
* host - the host the search result came from
* source - the source file on that host
* _raw - the raw text of the logged event.

The Zulip message contains:
* search name
* host
* source
* raw

The destination stream and message topic are configurable: the default
stream is "splunk" and the default topic "Splunk Alert". If the topic is
not provided in the URL, the search name is used instead (truncated if too
long. If a needed field is missing, a default value is used instead.

Example: "Missing source"

It is possible to configure a Splunk search to not include some values,
so I've provided defaults rather than return an error for missing data.
In practice, these fields are unlikely to be deliberately suppressed.

Note: alerts are only available for Splunk servers using a valid trial,
developer, or paid license.

I've added tests for the normal case of one search result, the topic from
the search name, and for a search missing one of the fields used. Tested
using Splunk Enterprise 6.5.1.

Fixes #3477
2017-03-07 21:48:26 -08:00
K.Kanakhin
1e441b8d7c uwsgi: Add master mode to the main uwsgi process.
- Enable `master` parameter for `uswgi` configuration.
  It allows cleaning leaked processes if the parent
  process is closed unexpectedly or with SIGKILL command.
  Child processes follow to the master and kill themselves
  after the main process.

Fixes #3855
2017-03-07 21:35:51 -08:00
Tim Abbott
6e442902e1 AdminZulipHandler: Don't print extra traceback for logged-out users.
This is not an interesting condition worth highlighting for sysadmins.

Fixes #3963.
2017-03-07 21:23:10 -08:00
Joshua Pan
b1e7ecdad2 user search: Hitting enter narrows to user PM.
Fixes #3874.
2017-03-07 21:05:56 -08:00
Tim Abbott
6a8dfe1f3f test_messages: Fix nondeterministic coverage issue. 2017-03-07 20:44:55 -08:00
K.Kanakhin
173f34b7aa user-presence: Add offline status to aggregated info.
- Add `OFFLINE_THRESHOLD_SECS` settings parameter
  to handle offline period.
- Set aggregated status to offline if user's status
  haven't changed for `OFFLINE_THRESHOLD_SECS` period.
- Add test for offline aggregated status.
2017-03-07 20:09:53 -08:00
K.Kanakhin
2f251dedaf user-presence: Add aggregated status to user presence info.
- Add aggregated status to user presence status dict.
- Add tests for aggregated presence status.
- Fix removing unused keys from status dict
  with aggregated data for user.

Fixes #3692
2017-03-07 20:09:53 -08:00
K.Kanakhin
6a801db1c2 missed-emails-sending: Move email sending to separate queue worker.
- Add new 'missedmessage_email_senders' queue for sending missed messages emails.
- Add the new worker to process 'missedmessage_email_senders' queue.
- Split aggregation missed messages and sending missed messages email
  to separate queue workers.
- Adapt tests for sending missed emails to the new logic.

Fixes #2607
2017-03-07 20:08:40 -08:00
K.Kanakhin
ea4b9cb609 production-helper: Fix sorting queue workers by name.
- Shell command `sort` depends on system locale and
  symbol `_` (underscore) is located after letters
  in the default locale of Travis instances. Otherwise,
  python sorting uses its own symbols ordering and
  underscore is located before letters. Changing the
  locale for `sort` shell command with adding environment
  variable doesn' t work on Travis instances. That's why
  It was decided to apply the same sorting command to both
  comparing lists.
2017-03-07 20:05:53 -08:00
Elliott Jin
3127ebfa3b test-backend: Raise zerver/views/events_register.py test coverage to 100%. 2017-03-07 19:47:16 -08:00
Umair Khan
1f60baba6b Handle social auth exception in auth_complete.
In case of an exception, we log it and return None which results in a
redirect to the login page.
2017-03-07 19:46:40 -08:00
Elliott Jin
fa9b8d8114 docs: Fix typos in events-system.md. 2017-03-07 19:46:16 -08:00
Tim Abbott
345ece0ee5 message view: Improve readability of dates and times. 2017-03-07 18:56:30 -08:00
Boris Yankov
890ff16b37 message view: Increase font weight of timestamps for readibility. 2017-03-07 18:56:05 -08:00
Archana BS
a6b5b03122 stats: Change time ranges for bar graph and pie chart.
- Change templates/analytics/stats.html to use 'Last
  Week', 'Last Month', 'Last Year' time ranges instead
  of 'Last 10 days', 'Last 30 days'.
- Change static/styles/stats.css to not set background
  color for default time option, for messages sent by
  client and message by recipient type.
- Change static/js/stats/stats.js to show only available
  time range options, and set background color for the
  default. The default is Last Month if it exists, and
  otherwise All Time.

Fixes: #3856
2017-03-07 17:25:58 -08:00
Tim Abbott
d681ef470d docs: Fully desupport the old iOS app. 2017-03-07 16:48:27 -08:00
Tim Abbott
d9eb011da1 docs: Extend discussion of package.json. 2017-03-07 16:39:50 -08:00
Yago González
155978fefd docs: Improve the frontend build process. 2017-03-07 16:37:09 -08:00
Raghav Jajodia
d52e08a25c analytics: Add a "Last updated" to the bottom of the stats page.
Fixes #3857.
2017-03-07 16:02:27 -08:00
Tim Abbott
ec16a3298d reactions: Expand click area for opening popover. 2017-03-06 22:26:12 -08:00
Brock Whittaker
ec9bad4096 Hide the emoji icon in message when emoji is selected.
This hides the emoji icon from the shown state when users select an
emoji from the popover.
2017-03-06 22:24:21 -08:00
Brock Whittaker
4d5aa3ddc9 Restyle and refactor .message_controls for better UX.
This refactors the .message_controls to stop relying on absolute
positioning and strange CSS, and throws them inline.

This also restyles so they hang to the right of the time which is now
always present.

Fixes: #3761.
2017-03-06 22:24:21 -08:00
Tim Abbott
dcb14ec58e jinja2: Fix mypy confusion caused by weird six import. 2017-03-06 22:24:07 -08:00
Tim Abbott
950e06cf32 populate_db: Remove unused Deployment import. 2017-03-06 00:11:53 -08:00
Tim Abbott
1c3dbdcefe models: Remove obsolete realm.deployment property.
We've now removed all of the code that accesses this.
2017-03-06 00:11:13 -08:00
Tim Abbott
10a52147fc zilencer: Remove obsolete create_deployment command. 2017-03-06 00:10:03 -08:00
Tim Abbott
e90df029bf create_realm: Eliminate obsolete deployment code.
Since we're not using this model anymore, we certainly don't need it
when creating realms.
2017-03-06 00:07:45 -08:00
Tim Abbott
8815a598d8 digest: Remove obsolete deployment code.
This system was quite complicated, and never had great semantics.

Eventually, we'll want some other system for gating which server
should generate digest emails for which realm controlled via the
database.
2017-03-06 00:05:21 -08:00
Tim Abbott
d286c5e68f feedback: Remove unnecessary realm_for_email.
This also has the side effect of removing the hardcoding of
feedback@zulip.com here.
2017-03-06 00:01:58 -08:00
Tim Abbott
6cbd0fcafa feedback: Move feedback logic out of queue_processors.py.
This will make it easier to unit test this logic in the future.
2017-03-06 00:01:57 -08:00
Tim Abbott
e1c1f96f9e zilencer: Eliminate submit_feedback indirection. 2017-03-06 00:01:57 -08:00
Tim Abbott
ed5b76f566 zilencer: Move feedback code to zerver/lib/feedback. 2017-03-06 00:01:57 -08:00
Tim Abbott
1f9d93bc96 submit_feedback: remove unused domainish variable. 2017-03-06 00:01:57 -08:00
Tim Abbott
9a08ef5545 zilencer: Remove FEEDBACK_TARGET forwarding logic.
This feature hardcoded zulip.com, and never really made much sense
("feedback" should generally go to the local server administrator, not
to the Zulip development community).
2017-03-06 00:01:57 -08:00
Tim Abbott
69061e6db4 zilencer: Remove obsolete lookup_endpoints_for_user endpoint.
This endpoint was part of the same obsolete system as
desktop_sso_dispatch.
2017-03-06 00:01:56 -08:00
Tim Abbott
9e8023843a zilencer: Remove obsolete desktop_sso_dispatch.
This feature has been obsolete since when Zulip was released as open
source software, since it's purpose was to avoid putting a "server
url" prompt in the desktop app, and now that prompt is required
anyway.
2017-03-06 00:01:47 -08:00
Eeshan Garg
70df1f5829 new-feature-tutorial: Recommend updating user documentation.
Fixes: #3876
2017-03-05 23:04:56 -08:00
Tim Abbott
89eb7636ba remove_push_device_token: Remove unused request argument. 2017-03-05 22:01:28 -08:00
Tim Abbott
657dfcbddc push: Move remove_push_device_token to library. 2017-03-05 19:15:17 -08:00
Tim Abbott
c0ad9c02fd push: Extract validate_token helper function. 2017-03-05 19:15:17 -08:00
Tim Abbott
271bd5a282 push: Move add_push_device_token to library. 2017-03-05 19:15:16 -08:00
Tim Abbott
410c0626a6 push: Pass apple alert via the zulip dict.
This completes the process of simplifying the interface of the
send_*_push_notification functions, so that they can effectively
support a push notification forwarding workflow.
2017-03-05 18:37:00 -08:00
Tim Abbott
fc192d6b3b push: Don't pass a UserProfile into send_apple_push_notification.. 2017-03-05 18:37:00 -08:00
Tim Abbott
393c4d2eaa push: Don't pass a UserProfile into _do_push_to_apns_service. 2017-03-05 18:37:00 -08:00
Tim Abbott
53c9e3b4ca push: Don't pass a full UserProfile into APNsMessage. 2017-03-05 18:37:00 -08:00
Tim Abbott
c8bfd568bc push: Pass devices list into send_apple_push_notification. 2017-03-05 18:36:58 -08:00
Tim Abbott
0ddaf5c610 push: Pass reg_ids list into send_android_push_notification.
This refactoring is preparation for being able to forward push
notifications to users on behalf of another Zulip server.

The goal is to remove access to the current server's database from the
send_*_push_notification code paths.
2017-03-05 18:36:07 -08:00
Tim Abbott
b1b2d8d2c7 push: Move handle_push_notifications to push_notifications.py. 2017-03-05 18:32:09 -08:00
sinwar
d8ff09cb42 requirements: Upgrade pycodestyle to latest version.
Fixes #3927.
2017-03-05 16:17:04 -08:00
sinwar
6f0564e9f4 python: Fix remaining bare excepts in codebase.
Fixes #2862.
2017-03-05 16:17:04 -08:00
Tim Abbott
08e1759ad0 bots: Replace bare excepts with targeted exceptions. 2017-03-05 16:17:04 -08:00
Steve Howell
a17deb144a Use data-stream-id in topics popover. 2017-03-05 15:44:44 -08:00
Steve Howell
8e2e406404 refactor: Extract stream_popover.js.
This module handles the popovers in the stream list--one for
stream actions and another for topic-specific actions.

The extraction was mostly straightforward, but I did move some
of the code related to the color picker to be more consistent
with how I organized the other click handlers.
2017-03-05 15:44:43 -08:00
Steve Howell
ba49962f9a refactor: Extract stream_popover_sub().
Part of this change moved a click handler from subs.js to
popover.js.
2017-03-05 15:44:43 -08:00
Steve Howell
6630b84dc0 Remove data-stream-name from subscription_settings. 2017-03-05 15:44:43 -08:00
Steve Howell
58b018858e refactor: Pass in sub to ajaxUnsubscribe(). 2017-03-05 15:44:43 -08:00
Steve Howell
761a0beb7e refactor: Rename variable in show_settings_for(). 2017-03-05 15:44:43 -08:00
Steve Howell
e703b0bfdb refactor: Remove stream_name param in update_stream_color(). 2017-03-05 15:44:43 -08:00
Steve Howell
f8819256b0 Use stream_id in update_subscription_properties(). 2017-03-05 15:44:43 -08:00
Steve Howell
419a3174f1 Send stream_id in stream/update events. 2017-03-05 15:44:42 -08:00
Steve Howell
0bb1af0fd9 Send stream_id in subscription updates. 2017-03-05 15:26:00 -08:00
Cynthia Lin
0f02031846 user docs: Add user guide for *View messages containing files or links*.
Fixes #3754
2017-03-05 14:17:25 -08:00
Steve Howell
95cdc744d9 refactor: Simplify code for renaming streams. 2017-03-05 11:55:09 -08:00
Steve Howell
c5757ac8fe refactor: Change params for subs.mark_subscribed().
We pass in sub instead of stream_name, to support callers that
already do lookups by stream id.

And then we make the second optional argument be subscribers, since
that is all we were using from the old `attrs` argument.
2017-03-05 11:55:09 -08:00
Steve Howell
2f8ecad295 Remove unused get_stream_name(). 2017-03-05 11:55:09 -08:00
Steve Howell
4f1108cc27 refactor: Pass in a sub to remove_user_from_stream(). 2017-03-05 11:55:09 -08:00
Steve Howell
190b2ab1d3 refactor: Pass in a sub to invite_users_to_stream(). 2017-03-05 11:55:09 -08:00
Steve Howell
8a4dee4a80 bug fix: Handle bad streams for compose-invite feature.
We now handle missing subs more gracefully when you click on the
link to invite somebody you at-mentioned in a stream message.
2017-03-05 11:55:09 -08:00
Steve Howell
6183a0d8b2 bug fix: Handle invalid streams in would_receive_message(). 2017-03-05 11:55:09 -08:00
Steve Howell
4b98ec0a12 bug fix: Handle errors in at-mention typeaheads.
If a stream doesn't exist, prevent executing code that leads
to needless warnings.
2017-03-05 11:55:09 -08:00
Steve Howell
434f228135 refactor: Avoid nesting in the compose invite handler.
We exit early now if email is undefined, rather than
having a big if statement.
2017-03-05 11:55:09 -08:00
Steve Howell
24631a7405 refactor: Pass in a sub to subs.toggle_pin_to_top_stream(). 2017-03-05 11:55:09 -08:00
Steve Howell
32c2dc63f1 refactor: Pass in a sub to subs.toggle_home(). 2017-03-05 11:55:09 -08:00
Steve Howell
3a93a7310e refactor: Pass in a sub to set_stream_property().
This helps us localize the legacy need to pass stream names
(vs. ids) to the back end to set stream properties.
2017-03-05 11:55:09 -08:00
Steve Howell
1904871d77 refactor: Start to deprecate get_stream_name().
When possible, we should use get_sub_from_target() instead of
get_stream_name(), not only because it often saves a lookup later,
but it also makes it easier to audit the code for name vs. id
bugs.  (When you rename a stream, there can be races where you
use the old stream name instead of the more durable stream_id).

This commit handles the easy cases where the caller directly
wanted the sub, not the name.
2017-03-05 11:55:09 -08:00
Steve Howell
df6d644788 refactor: Extract get_sub_for_target(). 2017-03-05 11:55:09 -08:00
Steve Howell
a4376efd0f refactor: De-dup code using subs.sub_or_unsub(). 2017-03-05 11:55:09 -08:00
Steve Howell
67e558f905 refactor: Pass in a full sub to sub_or_unsub(). 2017-03-05 11:55:09 -08:00
Steve Howell
c38bbea6b9 Add tests for subs.sub_or_unsub(). 2017-03-05 11:55:09 -08:00
Steve Howell
8c61bb69cc casper: Fix flakiness with uploading realm icon. 2017-03-05 11:42:43 -08:00
Tim Abbott
67219cf660 puppet: Use restart-server for weekly server restarts.
Using `supervisorctl restart all` carried longer downtime (since it
just restarts everything at the same moment) and was less under our
control; I'm not sure it had any advantages.
2017-03-05 11:36:10 -08:00
Tim Abbott
b6f53d6c14 coverage: bring zerver/lib/validator.py to 100% coverage. 2017-03-05 00:53:27 -08:00
Tim Abbott
2f8bb1b1cd coverage: Add test for REST requests to /json API unauthed. 2017-03-05 00:53:27 -08:00
Tim Abbott
c8e38aaa55 coverage: Add coverage for OPTIONS HTTP method. 2017-03-05 00:53:26 -08:00
Tim Abbott
e95f139308 coverage: bring zerver/lib/response.py to 100% coverage. 2017-03-05 00:53:26 -08:00
Tim Abbott
89decf6ded coverage: bring zerver/lib/request.py to 100% coverage. 2017-03-05 00:53:26 -08:00
Tim Abbott
e7ff3415ab coverage: bring test_helpers.py to 100% coverage. 2017-03-05 00:53:26 -08:00
Tim Abbott
546fb9199d coverage: bring test_classes.py to 100% coverage. 2017-03-05 00:53:26 -08:00
Tim Abbott
e3cfb256dd coverage: Bring zerver.lib.narrow.py to 100% coverage. 2017-03-05 00:53:26 -08:00
Tim Abbott
56b1f79fe3 integrations: Fix email integration being listed unconditionally. 2017-03-05 00:53:26 -08:00
Tim Abbott
464928fdcc bugdown: Fix mypy error with python 3 coverage. 2017-03-05 00:53:26 -08:00
Tim Abbott
a53240a47c test_subs: Fix buggy assertion statement. 2017-03-04 23:57:56 -08:00
Tim Abbott
5050e42212 test-backend: Document # nocoverage comments. 2017-03-04 23:47:16 -08:00
Tim Abbott
e7389b4162 test-backend: Require 100% coverage on tests by default. 2017-03-04 23:39:34 -08:00
Tim Abbott
6c12a49d04 test_auth_backends: Remove now-unnecessary compatibility code.
This code was added as part of the Django 1.10 migration to make our
tests work with both Django 1.8 and 1.10.  Now that we're on 1.10,
it's no longer required.
2017-03-04 23:38:46 -08:00
Tim Abbott
39704bac6c test_bugdown: Remove unused common_bugdown_test. 2017-03-04 23:35:46 -08:00
Tim Abbott
1a8bc5f383 coverage: Bring test_decorators to 100% coverage. 2017-03-04 23:34:28 -08:00
Tim Abbott
c73c3c52f8 test_email_mirror: Fix TestCommandMTA.
The test didn't actually use the mock, due to an incorrect import
path.
2017-03-04 23:28:48 -08:00
Tim Abbott
6ea3a9cb1d coverage: Bring test_templates.py to 100% coverage. 2017-03-04 23:28:48 -08:00
Tim Abbott
8d9cab2339 test_narrow: Use AssertionError properly. 2017-03-04 23:19:16 -08:00
Tim Abbott
d8171b2efc coverage: Bring tests.py to 100% coverage. 2017-03-04 23:17:36 -08:00
Tim Abbott
768307d921 coverage: Bring test_events to 100% coverage. 2017-03-04 23:12:32 -08:00
Tim Abbott
d4f0e394e9 test_unread: Bring to 100% test coverage.
This actually fixes a test bug where we weren't actually verifying
whether other users' messages were being marked as read.
2017-03-04 23:09:45 -08:00
Tim Abbott
538570b7c1 test_subs: Bring to 100% test coverage. 2017-03-04 23:07:56 -08:00
Tim Abbott
065651b4fe coverage: Exclude uncovered lines in test_signup. 2017-03-04 23:01:50 -08:00
Tim Abbott
ff9f827c9a coverage: Don't require coverage in six.PY2/PY3 branches. 2017-03-04 22:51:35 -08:00
Tim Abbott
5ee33e59b8 coverage: Don't require coverage for NotImplementedErrors. 2017-03-04 22:48:21 -08:00
Tim Abbott
401ae3db97 coverage: Don't complain about if False coverage.
This fixes a test failure on master.
2017-03-04 22:48:14 -08:00
Tim Abbott
bc0cd7eb90 coverage: Move coverage config to tools/coveragerc. 2017-03-04 22:48:05 -08:00
Tim Abbott
63664264b8 test-backend: Disable verbose coverage display. 2017-03-04 22:48:05 -08:00
Tim Abbott
60b6a56da8 deps: Upgrade handlebars to latest version.
Fixes #3939.
2017-03-04 22:05:23 -08:00
Rafid Aslam
33129059f4 deps: Upgrade and move handlebars from static/third to npm.
- Remove `handlebars.runtime.js` from static/third and fetch it from npm
- Upgrade `handlebars` to 3.0.3.

I change the test since there is a patch about line, written in
handlebars'
v2.0.0-beta.1 release note:
"Lines containing only block statements and whitespace are now removed."

Fixes part of #1709.
2017-03-04 21:49:02 -08:00
Tim Abbott
bd0d6bb9d2 docs: Add discussion of VFL to front-end-build-process.md.
Also, link to this from various Python files where relevant.
2017-03-04 21:14:17 -08:00
Tim Abbott
7a048133bf docs: Fix typo in link to translating docs. 2017-03-04 20:58:50 -08:00
Tim Abbott
b62cd866e1 docs: Significantly update static asset pipeline docs. 2017-03-04 20:58:30 -08:00
Tim Abbott
e150640ddd lint: Add lint rule for loading external scripts.
This is a common mistake (I'll add documentation on why in the next
commit), and this is a great hook for sending folks to the
documentation on our frontend build process.
2017-03-04 20:42:47 -08:00
Tim Abbott
90bc76cf87 base.html: Remove commented-out HTML5 shim code.
From reading the history, I think this was actually never uncommented
in any version of Zulip; and regardless we no longer support IE8.
2017-03-04 20:42:25 -08:00
Raghav Jajodia
c3dbce810e right-sidebar: Added clear-search button on user-list searchbar.
A clear-search option to clear the user-list searchbox has been added.
This feature was present in the main searchbar but absent elsewhere.
Fix a part of #3716.
2017-03-04 20:30:58 -08:00
Tim Abbott
233c5eb255 mypy: Add UserProfile import in avatar_hash.py. 2017-03-04 20:24:47 -08:00
Cynthia Lin
f7db3a7d3d user docs: Fix broken link in *Upload and share files* doc. 2017-03-04 19:07:46 -08:00
Saket Kumar
1079e516a4 README: Update GSoC section.
Updated GSoC section to indicate zulip is participating again in 2017.
2017-03-04 19:06:33 -08:00
Tim Abbott
d95412425a generate_realm_creation_link: Fix line-wrapping of help text. 2017-03-04 19:02:01 -08:00
feorlen
3c954096f6 generate_realm_creation_link: Check for an uninitialized database.
This provides a nice error message to users who miss a step in the
instructions.

Fixes #3672.
2017-03-04 19:01:01 -08:00
adnrs96
3f58e20993 Refactor: Change user_avatar_hash with user_avatar_path at all calls.
In this commit we change user_avatar_hash with user_avatar_path which
now returns paths to avatars based on the email hash.

Tweaked by tabbott to avoid an import loop.
2017-03-04 18:39:49 -08:00
Tim Abbott
5488de11e6 migrations: Renumber 0059_userprofile_quota to fix conflict. 2017-03-04 18:38:27 -08:00
Tim Abbott
0569f8fb5f Document using slow scaleway machines to reproduce casper failures.
Fixes #1110.
2017-03-04 18:23:35 -08:00
Philip Skomorokhov
866a7b06b2 upload: Limit total size of files uploaded by a user to 1GB.
Fixes #3884.
2017-03-04 18:08:30 -08:00
Cynthia Lin
777b7d4cb7 user docs: Add user guide for *Manage your uploaded files* feature.
Fixes #3723
2017-03-04 17:50:49 -08:00
Cynthia Lin
33e7ae1fd0 user docs: Mention file upload management in *Upload and share files*. 2017-03-04 17:50:49 -08:00
Cynthia Lin
9ed15fa100 user docs: Update *Mute a topic* doc with new Settings feature.
Fixes #3793
2017-03-04 17:48:42 -08:00
Cynthia Lin
ccbe0b56c3 docs: Document zulipbot and its usage.
Tweaked by tabbott to document why we need it.

Fixes #3771
2017-03-04 17:44:43 -08:00
Raghav Jajodia
4752eb39b4 help: Added user docs for change of email address. 2017-03-04 17:32:48 -08:00
Tim Abbott
80232425f4 user_settings: Clean up error messages and tests for email change. 2017-03-04 17:32:48 -08:00
Raghav Jajodia
cd2d798498 admin: Added realm option to prevent users from changing their email.
A realm option to prevent users from changing their email address is added.
Fixes #3777.
2017-03-04 17:32:48 -08:00
Tim Abbott
d25bfb88d3 lint: Ban importing zerver.models in database migrations.
This doesn't work correctly, but in a subtle way.
2017-03-04 17:32:48 -08:00
Tim Abbott
219c519186 migrations: Fix upgrade process for RealmAuditLog migration.
You aren't allowed to import from `zerver.models` in migrations.
2017-03-04 17:24:04 -08:00
Raghav Jajodia
ec77aa0dfb user_settings: Add auth check before confirm_email_change.
This isn't strictly necessary, but adds a little bit of extra security
to the overall email change flow.
2017-03-04 17:05:25 -08:00
Rishi Gupta
35f854a2fd analytics: Add test for do_aggregate_to_summary_table. 2017-03-04 16:46:09 -08:00
Rishi Gupta
8feea6c598 analytics: Add LoggingCountStat for number of users. 2017-03-04 16:46:09 -08:00
Rishi Gupta
51b7677db7 Add RealmAuditLog table and record user activation/deactivation events.
The RealmAuditLog will make it easier for server admins to replay history.
2017-03-04 16:45:44 -08:00
hackerkid
3fdad8b64a Align message info action lines vertically. 2017-03-04 16:26:41 -08:00
hackerkid
2f073d9999 Remove sender name from message info action lines. 2017-03-04 16:25:29 -08:00
hackerkid
dafee5abe5 Remove timestamp from message info popover. 2017-03-04 16:25:29 -08:00
Raghav Jajodia
4ef4026e6a requirements: Upgrade mypy to version 0.501. 2017-03-04 15:41:11 -08:00
Tim Abbott
ab2ce9d5e9 lint: Fix whitespace error with recent mypy annotations. 2017-03-04 15:41:11 -08:00
Tim Abbott
34ade097ca mypy: Work around obnoxious async error. 2017-03-04 15:39:53 -08:00
Tim Abbott
0afe832fc7 check-rabbitmq-consumers: Fix typing import issue. 2017-03-04 15:35:26 -08:00
Tim Abbott
899b59e9d6 dev_settings: Fix linter error in recent mypy work. 2017-03-04 15:34:09 -08:00
Tim Abbott
75e81253f2 mypy: Work around several new mypy bugs in 0.501. 2017-03-04 15:33:39 -08:00
Raghav Jajodia
a3a03bd6a5 mypy: Added Dict, List and Set imports.
Fixed mypy errors associated with the upgrade.
2017-03-04 14:33:44 -08:00
Rishi Gupta
1453a5bfda Change string_id of test zephyr realm from mit to zephyr.
Also changes Realm.is_zephyr_mirror_realm to use string_id=zephyr instead of
domain=mit.edu.
Part of a larger migration away from Realm.domain.
2017-03-04 12:18:01 -08:00
Steve Howell
b611ecfa1e Make get_user_id blueslip errors clear again.
We had a theory that get_user_id() errors were often due to race
conditions related to reloads, so we would only report missing
user ids if subsequent lookups failed 5 seconds later.  It turns
out we still get the blueslip errors, and now we don't get
meaningful tracebacks.  This change makes it so that errors
get reported immediately again.
2017-03-04 07:50:47 -08:00
Rishi Gupta
66371009e2 Set settings.TIME_ZONE to UTC.
If there are weird time-based regressions in the next couple of days, it's
probably due to this.
2017-03-03 19:00:02 -08:00
Rishi Gupta
a1813e004e Remove local datetimes from webhook messages.
"Local" datetimes are local to the server (or rather, are using
settings.TIME_ZONE), which in most cases is not what the recipient of the
message is expecting.
2017-03-03 19:00:02 -08:00
adnrs96
9eb47f108c Refactor: Change upload_avatar_image to accept two user profiles.
In this commit we just change the upload_avatar_image function to accept
two user_profiles acting_user_profile and target_user_profile. Basically
email param is dropped for a target_user_profile so that avatar's could
be moved lateron to user id based storage.
2017-03-03 18:15:15 -08:00
Brock Whittaker
9ba0db29e4 Change the content-wrapper to be absolutely positioned.
Now because it isn’t floating left it won’t slide down to a level below
the rest of the content when there are pixel rounding errors with
browser zoom.
2017-03-03 18:10:41 -08:00
Feorlen
6494b84193 Update WordPress webhook to say self-installed blogs are experimental.
Reword the doc to be clear that WordPress.com blogs are supported and
self-installed blogs are experimental. Change the screen captures to show
WordPress.com.

For more details, see:
original issue https://github.com/zulip/zulip/issues/3245
original PR https://github.com/zulip/zulip/pull/2691
2017-03-03 17:15:32 -08:00
Rishi Gupta
8bea47d6b5 analytics: Do a stylistic cleanup of TestProcessCountStat. 2017-03-03 16:12:12 -08:00
Rishi Gupta
6c784d6321 analytics: Refactor COUNT_STATS declaration to not repeat itself. 2017-03-03 16:11:28 -08:00
Rishi Gupta
20255e48a4 analytics: Change messages_sent_to_stream to a daily stat.
Analytics database tables are getting big, and so we're likely moving to a
model where ~all stats are day stats, and we keep hourly stats only for the
last N days.

Also changed the name because:
* messages_sent_* suggests the counts (summed over subgroup) should be the
  same as the other messages_sent stats, but they are different (these don't
  include PMs).
* messages_sent_by_stream:is_bot:day is longer than 32 characters, the max
  allowable length for a BaseCount.property.

Includes a database migration to remove the old stat from the analytics
tables.
2017-03-03 16:11:28 -08:00
Steve Howell
b8caf45262 Improve error checking for peer_add/peer_remove events.
If we get invalid events related to stream subscribers, we now
exit earlier to prevent ugly tracebacks.  We may eventually
want to upgrade some of these warnings to errors, once we fix some
of our live-update bugs.  In particular, we don't yet live-update
users when streams go from private to public, so if you add/remove
subscribers to a newly-public stream that a user still thinks is
private, they will not be able to handle the event through no
fault of the codepath that happens during the add/remove.
2017-03-03 16:03:50 -08:00
Sourav Badami
4616ee7762 Enable display of emoji as their alt codes in reactions.
This currently only supports this in emoji reactions, not in actual
emoji in message bodies, but it's a great start for people who want a
text-only view.

Tweaked to update the text by tabbott.

Fixes #3169.
2017-03-03 15:19:34 -08:00
Rishi Gupta
2bbfdeeb7b Fix more errors caught by mypy 0.501.
Another set of relatively easy to review changes.
2017-03-03 14:15:38 -08:00
Rishi Gupta
28d3af0965 Fix several new errors caught by mypy 0.501.
Clear out a bunch of easy to review errors, so we can focus on the more
complicated ones.
2017-03-03 14:12:52 -08:00
Steve Howell
024168d85d bug fix: Fix hotkeys for compose preview.
We have special code for closing a "compose preview", but
it should only apply to the enter key.  Before this fix, we
would do the "enter" logic for other hotkeys like "j".
2017-03-03 12:22:57 -08:00
Steve Howell
a6e1ab4fec hotkeys: Limit calls to ui.home_tab_obscured().
If you are typing a key like "q" in the compose box, there is no
need to check if the home tab is obscured, because the effect of
"q" is not limited by the message pane being opened.
2017-03-03 12:22:57 -08:00
Steve Howell
bd6107cc1d hotkeys: Alphabetize switch/case code blocks. 2017-03-03 12:22:57 -08:00
Steve Howell
3c948be436 hotkeys: Extract focus_in_empty_compose().
This saves a bit of unnecessary computation when you type
non-arrow keys, which is especially important in the compose
box for characters that seem ordinary, like "j" and "q", but
which have mappings in some cases.
2017-03-03 12:22:57 -08:00
Steve Howell
64e0e65bac hotkeys: Limit calls to tab_up_down().
If you are not hitting an arrow key, we should prevent doing the
complex logic in tab_up_down().
2017-03-03 12:22:57 -08:00
Steve Howell
a2653e3ff5 hotkeys: Process "ignored" hotkeys more efficiently. 2017-03-03 12:22:57 -08:00
Umair Khan
d934863d12 i18n: Sort frontend translations.
This commit uses the change done in #3897 to sort the frontend
translations.
2017-03-03 12:32:42 +05:00
Umair Khan
87c5ace24d i18n: Use deterministic order in translations.json.
Fixes: #3897
2017-03-03 12:32:17 +05:00
Harshit Bansal
521e8700d7 emoji: Update NotoColorEmoji emoji set.
Update the existing NotoColorEmoji set to include emoji additions
like gendered professions, rainbow flag, single parent families etc.

Fixes: #3861.
2017-03-02 19:07:34 +05:30
Rishi Gupta
4dc791f393 Clean up timestamps.py and add a test. 2017-03-01 23:03:56 -08:00
Rishi Gupta
95f5c96bec Canonicalize how we convert timestamps to UTC datetimes.
No change in behavior with this commit, just making it easier to write a
future lint rule.
2017-03-01 23:03:56 -08:00
Rishi Gupta
3348083017 docs: Add code style section about naive datetime objects. 2017-03-01 23:03:56 -08:00
Rishi Gupta
9dfefa0a3f actions.py: Use UTC instead of server timezone to determine log directory.
Standardizing the Zulip codebase to use UTC everywhere. Note that unlike
many recent commits in this line, this changes does result in a change in
behavior.
2017-03-01 22:54:28 -08:00
Rishi Gupta
3d07ac0c49 Change timezone-naive datetimes to use timezone.now() where safe to do so.
Change timezone-naive datetimes to use timezone.now() in cases where there
is no change in behavior.
2017-03-01 22:54:28 -08:00
Rishi Gupta
c388858e53 Fix timezone errors in ScheduledJob and digest creation filters.
datetime.utcnow() is a timezone-naive datetime. The Django ORM interprets it
in the settings.TIME_ZONE timezone (e.g. 'America/New_York' in the
development server). We perhaps haven't noticed errors yet since with
'America/New_York' all it means is that emails are sent 5 hours early, or a
slightly different set of messages are included in the digest.
2017-03-01 22:54:28 -08:00
Rishi Gupta
562bc6429c Replace datetime.now() with timezone.now() in Django ORM queries.
When you pass a naive datetime to the Django ORM, it uses settings.TIME_ZONE
for the time zone. In the development environment, both settings.TIME_ZONE
and datetime.now() use 'America/New_York', so there is no change in behavior
there. (fromtimestamp with no tz argument uses the same timezone as
datetime.now)

We are soon going to change settings.TIME_ZONE to UTC, so need to remove
naive datetimes from queries to the ORM.
2017-03-01 22:54:28 -08:00
Rishi Gupta
01a4615f6e Change datetime.now to timezone.now in active_user_stats_by_day.
This actually fixes previously broken behavior, since 'date' here gets
turned into the 'day' argument of seconds_active_during_day(day), where
tzinfo is set to UTC.
2017-03-01 22:54:28 -08:00
Rishi Gupta
0218422e96 Use time.time() instead of datetime.now() to measure elapsed time.
Both because it is more idiomatic and because we will soon start enforcing
that all datetimes in Zulip are timezone aware.
2017-03-01 22:54:28 -08:00
Rishi Gupta
2b2be8120f Change datetime.now(tz=X) to timezone.now().
datetime.now with a timezone set is equivalent to timezone.now() if it's
never being printed out, but the latter is cleaner and more idiomatic.
2017-03-01 22:54:28 -08:00
Tim Abbott
9b11993fa7 settings: Fix need to reload when changing time format.
I noticed while reviewing #3807 that we still haven't fixed this;
because timestamps are primarily displayed in the message view, fixing
this is trivial.
2017-03-01 22:43:19 -08:00
Tim Abbott
f037979fe0 zjsunit: Don't run tests on editor backup files. 2017-03-01 22:43:19 -08:00
Tim Abbott
97c23bc1ab compose: Rename 'New stream message' to 'New topic'.
This doesn't update documentation, because we need to update that
anyway to show screenshots of the new compose box.
2017-03-01 21:31:43 -08:00
Tim Abbott
342c436c68 Fix propagation of lightbox body clicks closing compose box.
Like most event handlers where one successfully did something
specific, this event handler should stop event propagation.

Fixes #3885.
2017-03-01 20:48:42 -08:00
PhilSk
53f3d84af2 attachment: Add 'size' field tracking size of uploaded files.
This tracking will make it possible in the future to limit the total
size of uploads on a per-user or per-organization basis.

Fixes #3774.
2017-03-01 15:58:21 -08:00
Pranjay Patil
8b003aa48d alert-words: Fix broken alert word UI.
This fixes the alert word UI in settings by updating the CSS property
referenced in the alert_word_settings_item.handlebars file.

Fixes #3823
2017-03-01 11:54:17 -08:00
Brock Whittaker
ddc30b6650 Fix vertical centering of unread message counts.
This fixes the vertical centering issue related to unread message
counts.

Fixes: #3862.
2017-03-01 11:47:49 -08:00
Tim Abbott
31bf60d3d8 Fix accidentally overriding alt-left with edit-last-message hotkey.
Apparently, our logic was broken on systems where altKey and metaKey
are different, because we didn't ignore hotkey combinations that
included altKey.

Fixes #3738.
2017-03-01 11:18:40 -08:00
Tim Abbott
d90f7c72a3 zephyr: Fix broken postgres regular expression logic and add tests.
Like many rare-case code with new tests, it turns out that the logic
for handling null characters in our Zephyr postgres query escaping
never worked, in multiple ways.  First, it always changed the second
character in s, not the current one being inspected, and second, the
value it replaced it with was no the correct postgres escape of the
null byte.  We fix this and add tests.

This completes the effort to get zerver/views/messages.py to 100%
test coverage.

Fixes #1006.
2017-03-01 10:38:48 -08:00
Tim Abbott
bc38870136 preview: Fix adding links in message editing.
When you edit a message to contain links, and URL previews are
enabled, previously we'd throw an exception, because the realm ID
wasn't included in the event.

Also adds a test so that we can have effective test coverage on this
codepath, though this history is actually that I found the bug through
writing this test :).
2017-03-01 10:38:47 -08:00
Tim Abbott
d754d257f2 PreviewTestCase: Use the actual queued event.
This makes the test significantly simpler and more faithful, but not
mocking the event put into queue_json_publish.
2017-03-01 10:37:55 -08:00
Tim Abbott
b6bf45b0da PreviewTestCase: Factor out open_graph_html variable. 2017-03-01 10:37:50 -08:00
hackerkid
b7a6826fda Add support for getting medium size profile images. 2017-03-01 09:57:30 -08:00
Tim Abbott
b0f53fd1a8 check-templates: Check left and right sidebars. 2017-03-01 09:08:09 -08:00
Tim Abbott
c21365cacf templates: Rename image-overlay.html to lightbox_overlay.html. 2017-03-01 09:03:35 -08:00
Tim Abbott
0712926b84 templates: Rename right-sidebar.html to right_sidebar.html. 2017-03-01 09:02:15 -08:00
Tim Abbott
748ec32349 templates: Rename left-sidebar.html to left_sidebar.html. 2017-03-01 09:00:51 -08:00
Tim Abbott
291cfa3c11 templates: Fix settings-sidebar.html usage. 2017-03-01 08:59:23 -08:00
Igor Tokarev
31dff09efa Support email changes for !avatar syntax.
Significantly modified by tabbott to avoid calling
get_user_profile_by_email in bugdown, and have 100% test coverage of
the views code.

Fixes #2041.
2017-02-28 21:56:04 -08:00
Tim Abbott
a1d296b802 report: Use DEVELOPMENT instead of DEBUG setting.
This fixes a weird issue where the following sequences of tests would fail:

test-backend
 zerver.tests.test_messages.PersonalMessagesTest.test_personal_to_self
 zerver.tests.test_report.TestReport.test_report_error
 zerver.tests.test_templates.TemplateTestCase.test_custom_tos_template

It appears that all 3 tests are required for the failure.

While it's not entirely clear what the cause is, a very likely factor
is that settings.DEBUG is special, and so changing it at runtime is
likely to cause weird problems like this.

We fix this by replacing it with settings.DEVELOPMENT, which has the
same value in all environments, but doesn't have this problem of being
a special Django thing.
2017-02-28 21:44:41 -08:00
Tim Abbott
1c73ddd4c6 docs: Advertise tagging strings for translation in a few places. 2017-02-28 20:41:40 -08:00
Tim Abbott
7fb406b889 lint: Expand lint check for use of .text() without i18n.
Fixes #3705.
2017-02-28 20:37:52 -08:00
Tim Abbott
d9ef6281fa lint: Clean json_error/JsonableError lint exceptions.
We primarily need to be checking for literal strings being passed in
without i18n tags, not for code that passes a constructed value in.
2017-02-28 20:26:18 -08:00
Elliott Jin
7ed10da4ad test-backend: Raise zerver/views/report.py test coverage to 100%. 2017-02-28 20:06:00 -08:00
Tim Abbott
49687272a9 bots: Fix indentation in bot_avatar_row.handlebars. 2017-02-28 20:02:23 -08:00
Brock Whittaker
b8f2685b18 Change bots actions to sidebar.
This changes the bot actions to a sidebar that resides in the settings
overlay.
2017-02-28 20:02:23 -08:00
Brock Whittaker
e9e722d48b Restyle individual bots.
This restyles the individual bots to be in a grid and to look more
modern than the last setup.
2017-02-28 20:02:23 -08:00
Brock Whittaker
def5323ef4 Restyle subscriber list in subscription settings panel.
This restyles the subscriber list in the subscription settings panel to
have a more padded and lighter aesthetic and replaces the dark red
buttons with transparent buttons that have only red borders and inner
text.
2017-02-28 16:47:15 -08:00
Steve Howell
976185da30 Streamline compose fading for presence updates.
We now only update the new element.
2017-02-28 16:40:10 -08:00
Steve Howell
ef9a28fa29 Simplify inserting users into right sidebar.
The test that is removed here was more confusing than useful.
2017-02-28 16:40:10 -08:00
Steve Howell
b83d10345a Extract update_user_row_when_fading(). 2017-02-28 16:40:10 -08:00
Steve Howell
c78e20450c Change activity.set_user_statuses to be set_user_status().
We only get one presence update at a time, so now the
activity.js function reflects that.
2017-02-28 16:26:01 -08:00
Steve Howell
5b96f8db9a Extract get_compare_function() in activity.js. 2017-02-28 16:26:01 -08:00
Steve Howell
339c9ad43b Remove unused my_fullname HTML class. 2017-02-28 16:26:01 -08:00
Steve Howell
bcfc3060c9 Remove unused device-related code in activity list.
This speeds up rendering big activity lists.  When we are ready
to add this back, we should measure the performance impact for
large lists.
2017-02-28 16:26:01 -08:00
Harshit Bansal
a05795c85c bot_data.js: Add get_all_bots_for_current_user() function.
This function can be used to get all the bots whether active or
inactive that belong to current logged in user.
2017-02-28 16:15:10 -08:00
Abhijeet Kaur
f0121973d2 bug fix: Fix error when admin renames a bot after reactivating it.
Fix administration page javascript issue of TypeError that occurs
due to undefined variable access in static/js/bot_data.js file.
Reactivating a bot was not updating the state in `bot_data`.
Sending an event on reactivating a bot fixes this issue.

Fixes: #2840
2017-02-28 16:10:53 -08:00
Rishi Gupta
15d60fa7ed Change now() to timezone.now() throughout codebase.
Change `from django.utils.timezone import now` to
`from django.utils import timezone`.

This is both because now() is ambiguous (could be datetime.datetime.now),
and more importantly to make it easier to write a lint rule against
datetime.datetime.now().
2017-02-28 16:03:37 -08:00
Rishi Gupta
bf6415cf72 analytics: Remove sidebar from /stats.
It's currently broken (e.g. see Issue #3713) and non-responsive. The whole
page needs to be styled anyway, so these can be added back once that
happens.
2017-02-28 15:50:57 -08:00
Tim Abbott
de604d7759 page_params: Reorganize page_params dict with plans.
page_params is kinda a monster object.  Ideally, we'd make it be
constructed in a much less haphazard fashion, and make sure that all
the useful data in it is available via the `/register` endpoint for
mobile/API.  This change reorganizes page_params to be sorted by data
source, which is an important prerequisite for doing that.
2017-02-28 14:58:54 -08:00
Tim Abbott
e86ed89986 page_params: scope presence_disabled in realm. 2017-02-28 14:58:53 -08:00
Tim Abbott
dfb7a57bec home: Refactor register_ret->page_params logic. 2017-02-28 14:45:03 -08:00
Tim Abbott
85caa87492 tests: Fix test_doc_endpoints with reformatted HTML. 2017-02-28 14:45:03 -08:00
K.Kanakhin
d9b10727fa server-version: Add server version to api endpoints.
- Add server version to `fetch_initial_state_data`.
- Add server version to register event queue api endpoint.
- Add server version to `get_auth_backends` api endpoint.
- Change source for server version in `home` endpoint.
- Fix tests.

Fixes #3663
2017-02-28 14:22:01 -08:00
adnrs96
fee774e6b6 Clean markdown_help.html to use 4 space indents. 2017-02-28 13:57:48 -08:00
adnrs96
2181434efd Clean portico_signup.html to use 4 space indents. 2017-02-28 13:55:20 -08:00
adnrs96
22264d6086 Clean portico.html to use 4 space indents.
Tweaked manually by tabbott for minor formatting improvements.
2017-02-28 13:54:59 -08:00
Tim Abbott
9f67feba0b invite_user: Add missing translation tag. 2017-02-28 13:53:21 -08:00
adnrs96
4e73e50f6f Clean invite_user.html to use 4 space indents. 2017-02-28 13:52:03 -08:00
adnrs96
8e76b81a15 Clean api_endpoints.html to use 4 space indents.
Tweaked a bit by tabbott.
2017-02-28 13:51:48 -08:00
adnrs96
0a2c771504 Clean authors.html to use 4 space indents. 2017-02-28 13:49:59 -08:00
adnrs96
bf2bccb6f8 Clean base.html to use 4 space indents. 2017-02-28 13:49:35 -08:00
Rishi Gupta
7a6d001592 signup: Make error message for a weak password more clear.
"Password is weak" sounds like an fyi rather than "we're going to stop you
from registering until you fix this".
2017-02-28 13:46:39 -08:00
Tim Abbott
5f684b8b51 css: Remove text-shadow usage.
This makes text look bad in Chrome on Linux; it happened to not cause
problems in production because our minifier broke it (see
https://github.com/yui/yuicompressor/issues/91), but text looked bad
in development.
2017-02-28 10:41:42 -08:00
Vivek Anand
620d75afc5 alert_words: Avoid redundant .lstrip().
We are applying .strip() on a string and thus we don't
need .lstrip() since .strip() already strips the left
side of the string.
2017-02-28 10:13:03 -08:00
Tim Abbott
1656c04517 drafts: Remove unnecessary label capitalization. 2017-02-28 10:10:12 -08:00
Aman Khantaal
f0a9b7e4a1 Drafts: Click on a message will open it for edit. 2017-02-28 10:10:12 -08:00
Umair Khan
802de53ede backend: Handle GitHub authentication failure.
In case of AuthFailed exception return None.
2017-02-28 09:55:37 -08:00
Raghav Jajodia
f140810ad9 Fix stray zerver/views/__init__.py in new-feature-tutorial.
That file was cleaned out a while ago :).
2017-02-28 09:45:56 -08:00
K.Kanakhin
23706a3c9e Add server error response for failed handlebars template compilation.
- Add stamp file creation for the failed templates compilation.
- Add error response to `home` route if stamp file exists. It appears
  just for the development environment.
- Add jinja2 template for failed handlebars templates compilation error.

Fixes #3650.
2017-02-28 09:44:08 -08:00
Elliott Jin
11ba94f11a test-backend: Raise zerver/views/integrations.py test coverage to 100%. 2017-02-28 09:31:06 -08:00
Elliott Jin
2ea0430bf1 Clean up timestamp formatting in Google Calendar bot. 2017-02-28 09:29:07 -08:00
Joshua Pan
8514df180b README.md: fix https://www.zulip.org link 2017-02-27 22:19:34 -08:00
hackerkid
8a2b7751a5 requirements: Move PyJWT to common.txt. 2017-02-27 16:04:49 -08:00
hackerkid
ea55b372ac requirements: Remove JWT.
We are using PyJWT, not JWT.
2017-02-27 16:04:49 -08:00
Brock Whittaker
2751fa44e6 Remove transition on compose box height.
The transition "all" by default also affected the transition
on the height change of the compose box which ended up making the
compose box appear to be laggy and choppy.
2017-02-27 15:59:49 -08:00
Tim Abbott
f6f2c62caf zulip-puppet-apply: Fix running it as ./zulip-puppet-apply. 2017-02-27 15:25:14 -08:00
Raghav Jajodia
27f80e7741 hotkeys: 'Esc' key on topic field closes the message_edit form.
Pressing Escape key when on topic field closes the message_edit form
Fixes #3796.
2017-02-27 00:22:18 -08:00
Feorlen
57e64daeb9 Explain Django "Invalid HTTP_HOST header" log message. 2017-02-27 00:13:32 -08:00
Harshit Bansal
bbcd927375 bot_data.js: Replace remove() with deactivate().
On receiving a `remove` event of type `realm_bot`, instead
of deleting the bot from `bots` dict, set it's `is_active`
flag to false.
2017-02-26 23:56:51 -08:00
Harshit Bansal
a900a2076a bot_data.js: Add is_active field to bot_dict. 2017-02-26 23:56:51 -08:00
Harshit Bansal
9d5be410af page_params: Modify bot_list to hold active as well as inactive bots.
Modify the `bot_list` to hold all the bots owned by an user
irrespective of whether the bot is active or inactive. Also
include the `is_active` field in `active_bot_dict_fields` to
distinguish between inactive and active bots.
2017-02-26 23:56:51 -08:00
Joshua Pan
4db73b4e91 README.md: change relative links to absolute links 2017-02-26 22:24:56 -08:00
Harshit Bansal
1948cb6a89 Add UI for changing the bot owners.
Add neccesary UI in #administration and #settings for
changing the bot owner. The bot owner select control
is rendered dynamically in order to avoid performance
issues in case of large number of users.

Fixes: #2719.
2017-02-26 21:39:22 -08:00
Harshit Bansal
8b11deedb3 views/users.py: Allow changing bot's owner.
Modify the `patch_bot_backend()` route to support
changing the bot owner.
2017-02-26 21:39:22 -08:00
Tim Abbott
9cd6bb4251 README: Tweak peer review stream docs. 2017-02-26 21:22:13 -08:00
Joshua Pan
75e8cd5a6a README.md: Document peer review stream. Fixes #3395. 2017-02-26 21:19:38 -08:00
Brock Whittaker
a66cd814af Huge performance update for subscriber list in streams.
Previously the mechanism worked such that the innerHTML was being
appended to directly potentially thousands of times which has horrific
performance implications. By concating all the strings together before
appending to the HTML it all gets rendered in one chunk without forcing
a re-render of previous elements. Performance is ~15x-20x faster now.
2017-02-26 21:11:23 -08:00
Tim Abbott
8691f1466a populate_db: Disable use of memcached when populating database.
This fixes an issue where one would get errors of the form:

`ValueError: unsupported pickle protocol: 3`

in a `run-dev.py` server run against Python 2 if you ran `provision`.
Provision currently runs `populate_db` with Python 3, storing Python 3
based data in memcached, which then can't be read by Python 2.
2017-02-26 21:08:47 -08:00
Elliott Jin
6bdefb92e9 test-backend: Raise zerver/views/zephyr.py test coverage to 100%. 2017-02-26 20:54:25 -08:00
K.Kanakhin
132534b3bb realm-icon: Add realm icon frontend tests. 2017-02-26 19:55:02 -08:00
adnrs96
a4f99fdb22 Clean search_operators.html to use 4 space indents. 2017-02-26 19:33:39 -08:00
adnrs96
9320fbd1a0 Clean accounts_home.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
05ad108268 Clean zulipchat_migration_tos.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
8a08f39cde Clean tutorial_finale.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
d7ed6bd645 Clean terms.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
74b6978cc1 Clean settings_overlay.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
92d6d5a213 Clean reset_emailed.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
3664236713 Clean reset_confirm.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
aba825f858 Clean reset.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
35b3daacf3 Clean missed_message_email.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
8f5670dfbc Clean logout.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
11bf32073d Clean find_my_team.html to use 4 space indents. 2017-02-26 19:32:21 -08:00
adnrs96
5116f00b2a Clean drafts.html to use 4 space indents. 2017-02-26 19:32:20 -08:00
adnrs96
07b2fe7d27 Clean debug.html to use 4 space indents. 2017-02-26 19:32:20 -08:00
adnrs96
2465191a9a Clean deactivated.html to use 4 space indents. 2017-02-26 19:32:20 -08:00
adnrs96
15414aaeab Clean about.html to use 4 space indents. 2017-02-26 19:32:20 -08:00
adnrs96
0b9669d1df Clean create_realm.html to use 4 space indents. 2017-02-26 19:32:20 -08:00
adnrs96
f37d354cc5 Clean accounts_send_confirm.html to use 4 space indents. 2017-02-26 19:32:20 -08:00
Tomasz Kolek
e1d73ea36f github: Add list and fixtures for ignored events to webhook. 2017-02-26 19:17:53 -08:00
Tomasz Kolek
349835e619 Add PR edited, assigned and unassigned to github webhook integration. 2017-02-26 19:16:12 -08:00
Sampriti Panda
fcfa3123d3 Fix compose box opening when clicking drafts button. 2017-02-26 18:37:03 -08:00
Tim Abbott
74a3c4a13f bugdown: Add a Zulip emoji test. 2017-02-26 18:30:16 -08:00
Harshit Bansal
40d137d621 bugdown: Change rendered emoji image to unicode/<codepoint>.png.
Use `name_to_codepoint.json` file (and the similar structure in
emoji_codes.js) to map emoji names directly to codepoints and change
the rendered emoji image to `unicode/<codepoint.png>` rather than
`<emoji_name>.png`.

Fixes: #3539.
2017-02-26 18:30:15 -08:00
Harshit Bansal
3651a432d5 build_emoji: Add name_to_codepoint dict to emoji_codes.js file. 2017-02-26 18:28:42 -08:00
Harshit Bansal
1b0d3cbb39 tools/build_emoji: Generate name_to_codepoint.json file.
Generate the `name_to_codepoint.json` file in build_emoji which will be
used by bugdown/ to map emoji names to codepoints directly.
2017-02-26 18:28:42 -08:00
Harshit Bansal
bc4aef0bc7 emoji: Move zulip-emoji to images/emoji/unicode.
Move zulip-emoji from its current location `images/emoji` to
`images/emoji/unicode` and add a symlink in `images/emoji`
to zulip.png in `images/emoji/unicode`.
2017-02-26 18:28:41 -08:00
Elliott Jin
be57d49beb Google Calendar bot: Populate events array directly. 2017-02-26 18:05:46 -08:00
Elliott Jin
31d777a138 Google Calendar bot: Include time zone offsets in timestamps.
Fixes: #3769
2017-02-26 18:05:46 -08:00
Steve Howell
c6069bc9cd Reformat user_presence_row.handlebars to have 4-space indents. 2017-02-26 16:18:02 -08:00
Steve Howell
eed41bfd0a Compare recipients using to_user_ids to fix live updates.
If you send a group PM from the home view, and then one of the
recipients changes their email, and then you send a group PM
to the same recipients, we need to make sure we don't create
a spurious recipient bar.  This fix makes this happen by
changing util.same_recipient() to look at user ids instead of
emails.
2017-02-26 16:18:02 -08:00
Steve Howell
9791e2f570 Populate focused_recipient.to_user_ids in compose_fade.js. 2017-02-26 16:18:02 -08:00
Steve Howell
4ae81d9063 Populate message.to_user_ids in message_store.js. 2017-02-26 16:18:02 -08:00
Steve Howell
df2abf0529 Populate message.to_user_ids in compose.js. 2017-02-26 16:18:02 -08:00
Steve Howell
49496cee58 Remove message param from compose.snapshot_message(). 2017-02-26 16:18:02 -08:00
Steve Howell
1daa4e3279 Extract people.email_list_to_user_ids_string(). 2017-02-26 16:18:02 -08:00
Steve Howell
6c39b4775c node test: Add tests for compose.js. 2017-02-26 16:18:02 -08:00
Steve Howell
9c63e055e2 Simplify create_message_object() for PM fields.
We now only populate PM fields if the message type is
private, and we make only one call to compose.recipient().
2017-02-26 16:18:02 -08:00
Steve Howell
4d0d18ba14 Use stream_id in recipient comparisons.
Using stream_id in recipient comparisons fixes a
bug in this scenario: go to home view, send message
to stream, wait for admin to rename stream, send
another message to the stream.  Before this change,
the stream name would live-update but you'd get a
spurious recipient bar due to the prior message still
having the old stream name in places internally.

There were other ways to fix the live-update glitch,
but it's just generally cleaner to do stream id
comparisons.

Part of this change is to add stream_id to
compose_fade.set_focused_recipient().
2017-02-26 16:18:02 -08:00
Steve Howell
c02cf5dd5c Extract compose_fade.should_fade_message(). 2017-02-26 16:18:02 -08:00
Steve Howell
a38bafe6ef Add compose_fade unit tests. 2017-02-26 16:18:02 -08:00
Steve Howell
96ca684d40 Remove feature_flags.fade_users_when_composing. 2017-02-26 16:18:02 -08:00
Steve Howell
b3dfa79482 Remove obsolete util.same_major_recipient(). 2017-02-26 16:18:02 -08:00
Steve Howell
807afc87ba Remove feature_flags.fade_at_stream_granularity. 2017-02-26 16:18:02 -08:00
Steve Howell
49ab8035f8 Populate stream_id when composing messages. 2017-02-26 16:18:02 -08:00
Steve Howell
98a627cba8 Add message.type guard to add_subject_links(). 2017-02-26 16:18:02 -08:00
Elliott Jin
f3cd3e8b8d test-backend: Raise zerver/views/invite.py test coverage to 100%. 2017-02-26 16:15:25 -08:00
Elliott Jin
cebc67f9b0 test-backend: Raise zerver/views/unsubscribe.py test coverage to 100%. 2017-02-26 16:13:35 -08:00
hackerkid
9e0d3262bb Increment provision version to upgrade python dependencies. 2017-02-26 16:12:31 -08:00
Tim Abbott
4090d409a4 requirements: Install cffi and pycparser in production.
It's needed for the argon2 password hasher.
2017-02-26 16:12:31 -08:00
hackerkid
9e6a7f0112 requirements: Upgrade cchardet to 1.1.3. 2017-02-26 15:59:23 -08:00
hackerkid
2bb4144e1c requirements: Upgrade pyasn1 to 0.2.3. 2017-02-26 15:59:23 -08:00
hackerkid
d1e85a654c requirements: Upgrade sphinx to 1.5.3. 2017-02-26 15:59:23 -08:00
hackerkid
e09093608b requirements: Upgrade boto to 2.46.1. 2017-02-26 15:59:23 -08:00
hackerkid
1119f75ba6 requirements: Upgrade w3lib to 1.17.0. 2017-02-26 15:59:23 -08:00
hackerkid
0a008def24 requirements: Upgrade Twisted to 17.1.0. 2017-02-26 15:59:23 -08:00
hackerkid
18b9c201ed requirements: Upgrade transifex-client to 0.12.4. 2017-02-26 15:59:23 -08:00
hackerkid
bcd8fca8ee requirements: Upgrade traitlets to 4.3.2. 2017-02-26 15:59:23 -08:00
hackerkid
c4fd148b42 requirements: Upgrade social-auth-core to 1.2.0. 2017-02-26 15:59:23 -08:00
hackerkid
5f49da7f50 requirements: Upgrade social-auth-app-django to 1.1.0. 2017-02-26 15:59:23 -08:00
hackerkid
7d895ae998 requirements: Upgrade Scrapy to 1.3.2. 2017-02-26 15:59:23 -08:00
hackerkid
cab584f803 requirements: Upgrade scandir to 1.5. 2017-02-26 15:59:23 -08:00
hackerkid
89c23834cb requirements: Upgrade requests_oauthlb to 0.8.0. 2017-02-26 15:59:23 -08:00
hackerkid
9d01b9f4a9 requirements: Upgrade requests to 2.13.0. 2017-02-26 15:59:23 -08:00
hackerkid
672245f72e requirements: Upgrade regex to 2017.2.8. 2017-02-26 15:59:23 -08:00
hackerkid
ea56d87f72 requirements: Upgrade python-ldap to 2.4.32. 2017-02-26 15:59:23 -08:00
hackerkid
77c9d3e382 requirements: Upgrade pytest-runner to 2.11.1. 2017-02-26 15:59:23 -08:00
hackerkid
0b3d21964a requirements: Upgrade Pygments to 2.2.0. 2017-02-26 15:59:23 -08:00
hackerkid
66817cd118 requirements: Upgrade prompt-toolkit to 1.0.13. 2017-02-26 15:59:23 -08:00
hackerkid
b4f4784764 requirements: Upgrade Markdown to 2.6.8. 2017-02-26 15:59:23 -08:00
hackerkid
34c55ce461 requirements: Upgrade lxml to 3.7.3. 2017-02-26 15:59:23 -08:00
hackerkid
b6a595c5a3 requirements: Upgrade Jinja2 to 2.9.5. 2017-02-26 15:59:23 -08:00
hackerkid
2a2328b725 requirements: Upgrade ipython to 5.3.0. 2017-02-26 15:59:23 -08:00
hackerkid
3810f5ffea requirements: Upgrade httplib2 to 0.10.3. 2017-02-26 15:59:23 -08:00
hackerkid
767f21c397 requirements: Upgrade google-api-python-client to 1.6.2. 2017-02-26 15:59:23 -08:00
hackerkid
f61bfb0186 requirements: Upgrade fonttools to 3.7.2. 2017-02-26 15:59:23 -08:00
hackerkid
6b672ea992 requirements: Upgrade django-auth-ldap to 1.2.9. 2017-02-26 15:59:23 -08:00
hackerkid
e5a1ccbed6 requirements: Upgrade defusedxml to 0.5.0. 2017-02-26 15:59:23 -08:00
hackerkid
d50efc6c4e requirements: Upgrade cryptography to 1.7.2. 2017-02-26 15:59:23 -08:00
hackerkid
903611c4f5 requirements: Upgrade certifi to 2017.1.23. 2017-02-26 15:59:23 -08:00
Tim Abbott
fc56141550 settings: Fix typo in icon upload. 2017-02-26 12:42:58 -08:00
Tim Abbott
4ea997493b events: Normalize realm_icon events to be standard.
This lets us save on semi-duplicate code, both in server_events.js and
in zerver/lib/events.py, and makes our event structure a bit more
predictable.
2017-02-26 12:16:07 -08:00
K.Kanakhin
257bb40698 realm-icon: Add realm icon feature.
- Add realm icon fields to realm model.
- Add migration for new realm model's field.
- Add views for icon uploading and deleting.
- Add routes for realm icons views.
- Add JS widget for realm icon upload setting.
- Add realm icon upload to administration
  organization setting.
- Add tests for realm icons.

Fixes #3660.
2017-02-26 12:16:07 -08:00
Tim Abbott
20b655016d js: Move admin.js further down the list.
This makes it reasonable for it to depend on libraries like widgets.js.
2017-02-26 12:16:07 -08:00
Tim Abbott
c5ed119f89 upload: Rename BadImageError exception to not mention avatars.
This is preparation for using that function to decode realm icons as
well.
2017-02-26 12:16:07 -08:00
K.Kanakhin
9ce218154e realm-icon: Move upload widget to separate file.
This makes it possible to use the upload widget in the realm icon
organization settings on frontend.
2017-02-26 12:15:41 -08:00
Tim Abbott
5a204d7c84 subs: Fix capitalization in stream privacy modal. 2017-02-25 18:36:48 -08:00
Tim Abbott
bd03bb76fd subs: Remove unnecessary data-is-private variable. 2017-02-25 18:33:07 -08:00
Harshit Bansal
f20993787c subscriptions: Add a modal for changing stream privacy.
Change the remaining "Admin settings" with a button, namely
changing a stream's privacy, to instead be a "[Change]" link
opening a confirmation modal.

Fixes: #3493.
2017-02-25 18:23:15 -08:00
Harshit Bansal
1d33c759e4 subs.js: Make change_stream_privacy() function global. 2017-02-25 18:23:15 -08:00
Elliott Jin
8decddb44b Clean up Google Calendar integration docs.
This change fixes a broken link, fixes minor typo, and includes some minor
rewording for clarity / consistency.
2017-02-25 18:20:58 -08:00
Elliott Jin
f038cd47d9 test-backend: Raise zerver/views/realm.py test coverage to 100%. 2017-02-25 18:18:29 -08:00
Elliott Jin
b2b1977138 docs: Fix typo in new-feature-tutorial.md. 2017-02-25 00:53:02 -08:00
Cynthia Lin
07d1637c96 frontend: Fix edit header display height.
Header navbar covers the entire Mac OS X old Zulip desktop app page; this should fix that error.
2017-02-24 15:21:20 -08:00
Brock Whittaker
c4d50f505f Make compose preview box less editable-looking.
This adds a slight background color and a cursor to show that editing
is disabled.
2017-02-24 15:07:33 -08:00
Brock Whittaker
9ee5ac6d23 Redesign compose box.
This redesigns it to closer to the new implementation design.
2017-02-24 15:07:33 -08:00
Brock Whittaker
c35d821786 Restyle uploaded files table.
This restyles the uploaded files table to be lighter, more minimal, and
easier to parse than the previous table.
2017-02-24 15:05:06 -08:00
Brock Whittaker
e504eaaa68 Change time render to be client-side and formatted.
This changes the time render to be done on the client-side and
therefore take advantage of knowing the client’s timezone, along with
being formatted in a more human-parseable way.
2017-02-24 15:05:06 -08:00
Brock Whittaker
434317b4cc Add "all" and "subscribed" deeplink for subscriptions.
This adds a deep link to “all” which is to show all streams,
along with "subscribed" for only streams you are subscribed to.
2017-02-23 15:34:30 -08:00
Brock Whittaker
461066cab9 Add deep linking to #subscriptions/new and #subscriptions/:stream_id.
This mechanism allows for a user to deep link to a particular
subscription or the form for creating a new subscription.
2017-02-23 15:34:30 -08:00
Brock Whittaker
6a7369b2b6 streams: Remove unnecessary subscriptions header arrow.
This removes the arrow from the subscriptions header at full
widths where the arrow is not required because the subscription
settings/stream creation prompt don't take up the full width of
the screen and require an arrow to go back to the streams list.

Fixes: #3762.
2017-02-23 14:27:35 -08:00
Brock Whittaker
0f9a5108fc settings: Change admin pages to have readonly view for non-admins.
This changes the layout of administration for non-administrators such
that they can view organization settings and emoji settings and
displays everything as readonly unless they have the capability to edit.

For now, we just enabled this for the emoji settings and organization
settings features.
2017-02-23 14:20:31 -08:00
Brock Whittaker
3bb22a6965 Remove all .expectOne statements in settings.
This removes all the .expectOne statements and replaces with a
single broad stroke .hide() that doesn't check if they exist,
but rather just ensures they are hidden by default until triggered.
2017-02-23 14:18:25 -08:00
Brock Whittaker
5fc0c0b6ac Fix the styling for drafts.
This fixes the appearance for drafts to be uniform with the rest of the
site along with general polishing.
2017-02-23 13:00:56 -08:00
Umair Khan
5bf83f9e0a change-email: Implement confirmation flow.
This adds to Zulip support for a user changing their own email
address.

It's backed by a huge amount of work by Steve Howell on making email
changes actually work from a UI perspective.

Fixes #734.
2017-02-23 03:15:17 -08:00
Sampriti Panda
1929cc5190 Implement persistent drafts functionality
* Created a drafts modal to display/restore/delete drafts
* Created a Draft model to support storing draft data in localstorage
* Removed existing restore-draft functionality
* Added casper and node tests for drafts functionality

Fixes #1717.
2017-02-23 02:58:23 -08:00
Brock Whittaker
8b22b94ab1 Add a LocalStorage wrapper for Zulip.
This is a wrapper that allows for versioning and migrations with
localStorage along with safe storage of data that respects data types.
2017-02-23 02:58:22 -08:00
Tim Abbott
ce91a43eee docs: Expand discussion of database schema migrations.
This covers the standard multi-step process for doing large
migrations, as well as other important properties to consider when
writing migrations.

Also documents the new Django 'atomic=False' option.

Fixes #1332.
2017-02-22 23:44:35 -08:00
Tim Abbott
32c2982299 docs: Document migration atomicity issues. 2017-02-22 23:35:37 -08:00
sinwar
483a351d44 Upgrade to argon password hasher.
The Argon2 password hasher is the currently recommended password
hasher for Django.

Fixes #3362.
2017-02-22 23:29:12 -08:00
ausDensk
5efb072e63 Change screenshot for HomeAssistant integration docs. 2017-02-22 23:27:43 -08:00
Tim Abbott
fe0c4cad85 check-rabbitmq-consumers: Go back to hardcoding for now.
This should fix the production test suite in Travis CI, so that we can
debug what's broken here offline.
2017-02-22 22:58:59 -08:00
Tim Abbott
e15a661720 accounts: Remove unhelpful avatar size advice. 2017-02-22 22:50:16 -08:00
Brock Whittaker
c7349178f0 Re-add "Delete Avatar" button to "Your account".
This re-adds the deleted "Delete Avatar" button back to the
settings/your-account tab view in the overlay, which only appears
if you do not currently have a gravitar.
2017-02-22 22:50:16 -08:00
Steve Howell
03386f1485 avatar live updates: Do full re-render.
We now sweep all active messages for avatar changes and update
the message items and re-render, rather than patching the
DOM.  This avoids some quirks that happen when subsequent messages
get sent and we re-render previous messages out of the message
store.

Our approach here is similar to how we do full-name updates.
2017-02-22 22:46:44 -08:00
lonerz
d09c8b42c1 docs: Update README.md with @zulipbot details. Fixes #3752. 2017-02-22 22:38:06 -08:00
Tim Abbott
cf444203c4 docs: Update email configuration documentation.
Fixes #2958.
2017-02-22 22:26:43 -08:00
Tim Abbott
d2f9152c43 settings: Make it possible to override EMAIL_BACKEND.
Fixes #3699.
2017-02-22 22:26:43 -08:00
Tim Abbott
8c1285924e prod_settings_template: Move email configuration up.
This reflects the fact that you definitely need to configure this, but
you don't have to configure any of the auth backends, really.
2017-02-22 22:26:43 -08:00
Tim Abbott
7964408633 prod_settings_template: Move ALLOWED_HOSTS up and clarify. 2017-02-22 22:26:43 -08:00
Tim Abbott
e208002002 docs: Improve install discussion of settings. 2017-02-22 22:26:43 -08:00
Rishi Gupta
42fc317262 developer docs: Add doc for analytics subsystem. 2017-02-22 22:12:40 -08:00
Tim Abbott
8dba310bee messages: Remove some unnecessary zephyr code paths.
The comments explain why this change is correct.  This change is
useful because it's better to not have dead code paths, both because
it makes our life easier for coverage analysis, and because the else
statement provided the illusion that it could actually happen.

If the analysis in that comment is wrong, we'd rather have a 500 error
so we fix the bug than things silently sorta working.
2017-02-22 20:51:25 -08:00
Tim Abbott
ff37524db6 messages: Add test coverage for IRC mirroring code path. 2017-02-22 20:51:25 -08:00
Tim Abbott
8875deff47 test_messages: Add a message edit permissions test. 2017-02-22 20:51:25 -08:00
Tim Abbott
948e1bbd0a update_message_backend: Use access_message.
This continues our campaign of removing direct queries on the Message
and UserMessage tables that could not follow our security policy.
2017-02-22 20:51:25 -08:00
Tim Abbott
442066da12 messages: Remove unused json_update_message. 2017-02-22 20:51:25 -08:00
Tim Abbott
f20ade041a messages: Add test coverage for is_search code path. 2017-02-22 20:51:25 -08:00
Tim Abbott
64434e04a1 messages: Fix empty condition for muted streams.
This fixes a sqlalchemy warning (that caused unnecessary complexity in
this query).
2017-02-22 20:51:23 -08:00
Tim Abbott
a079bcdce1 get_old_messages: Add LARGER_THAN_MAX_MESSAGE_ID constant. 2017-02-22 20:50:15 -08:00
Tim Abbott
ff65b6b842 get_old_messages: Remove unnecessary >= max_message_id query. 2017-02-22 20:47:48 -08:00
Tim Abbott
05e7ab3a5a test_narrow: Fix use_first_unread_anchor tests requesting 0 before/after. 2017-02-22 20:47:48 -08:00
Tim Abbott
6f0410774c sqlalchemy: Fix most sqlalchemy deprecation warnings.
Fixes #2732.
2017-02-22 20:47:48 -08:00
Tim Abbott
66f016edbb zephyr: Fix zerver_message tables scans due to regex in queries.
This arguably regresses the Zephyr experience, in that we no longer
consider 'foo.d.d.d.d.d' to be something that gets narrowed in with
the rest, but that's a pretty rare use case anyway.

In practice, using that many '.d's anyway only happens a few times a
year.
2017-02-22 20:47:46 -08:00
adnrs96
27c0d93ecc Clean message_history.html to use 4 space indents. 2017-02-22 20:36:12 -08:00
adnrs96
aa194f8ea9 Clean image-overlay.html to use 4 space indents. 2017-02-22 20:36:12 -08:00
adnrs96
77f412f05f Clean bankruptcy.html to use 4 space indents. 2017-02-22 20:36:12 -08:00
adnrs96
3acf8b050d Add Django and html singleton tags support to pretty print.
In this commit we are modifying pretty print tool to support
Django and html singleton tags. For Addition of html singleton
tags template parser was modified to emit psudeo
html singleton end tags to accompany html singleton tags and
token class was updated to have line_span field.
2017-02-22 20:21:58 -08:00
adnrs96
1458d0d3a2 Clean subscription_creation_form handlebar to use 4 space indents. 2017-02-23 07:14:41 +05:30
adnrs96
cfe57da14b Clean message_group handlebars to use 4 space indents. 2017-02-23 07:14:41 +05:30
adnrs96
13b7247ae2 Clean invite_subscription handlebar to use 4 space indents. 2017-02-23 07:14:41 +05:30
adnrs96
5b5a0bdb80 Improve check-templates error handling.
In this commit we improve the way errors are handled in our
template parser and thus improving the displayed messages in
case of errors. Eg. Errors in case of unbalanced quotes now
makes more sense displaying line and column information
including line where error might be sourced.
2017-02-22 17:39:12 -08:00
Steve Howell
fa31ad35c9 Fix display of changed avatars in old messages (page_params).
Our client code will now receive avatar_url in
page_params.people_list during page load, so it will be
able to use more current urls for old messages (the client
already had some logic for that and was just missing the
data).

We also add avatar_url to the realm_user/add event.

When we change the avatar, we make sure to always send a
realm_user/update event (even for bots).

We also needed to add avatar_version and
avatar_source to our active users cache.
2017-02-22 07:57:03 -08:00
Steve Howell
8de72184e1 Fix avatar message display regression from 1.5 release.
In f75af94984 I added some
lines of code that made it so that live updates for avatar
urls would affect messages currently in the browser.

This change worked well when the live update actually happened,
but then the next time the user would reload, the avatar in
the message pane would regress back to showing the avatar urls
from the server (which could have caching issues of their own).

This fix removes a couple lines of code that had the intended
effect of making all of your messages from any given sender
show the same url (good) but which generally grabbed
the url from an old message (bad).

After this fix, we go back to having old messages possibly
showing the old avatar urls, but new messages will display the
new avatar.

(There are lots of moving parts in the avatar system, because
not only do browsers cache image urls, but our server caches
messages and recipient info, so there have been "fixes" to
avatars since this change that are valid fixes in their own
right but not directly relevant to this commit.)
2017-02-22 07:57:03 -08:00
Steve Howell
9d5a631650 Add test_change_avatar_fields().
This adds a temporary, insignificant change to apply_events().
2017-02-22 07:57:03 -08:00
Tim Abbott
b81add60fe check-rabbitmq-consumers: Fix queue_workers call. 2017-02-22 00:48:43 -08:00
Sourav Badami
03861e5418 docs: Fix typo in new-feature-tutorial.md. 2017-02-22 00:37:59 -08:00
Tim Abbott
160891381a test_events: Add comments for do_test_subscribe_events. 2017-02-22 00:34:12 -08:00
Tim Abbott
aa6567ee34 queue_workers: Fix confusing --queue_type argument name. 2017-02-22 00:23:26 -08:00
Tim Abbott
2768be7fdf travis: Add logs to rabbitmq consumer debug output. 2017-02-22 00:21:22 -08:00
Tim Abbott
19896460f0 nagios: Fix RabbitMQ Nagios checks running Django as root.
This can cause problems by making the /var/log/zulip files owned by
root (not zulip) and thus not writable by the Zulip user.
2017-02-22 00:20:57 -08:00
Tim Abbott
53686fc5ac zproject: Delete config for old Django templates.
This configuration was effectively never used for anything.
2017-02-22 00:01:33 -08:00
Tim Abbott
a580e7088d email: Send an event when email addresses change. 2017-02-21 23:42:46 -08:00
Tim Abbott
e051336ff6 emoji: Tweak emoji reactions CSS to add hover effects.
This provides a fairly intense highlighting of when you're hovering
over a given emoji reaction element.

We may want to tone down the color a bit; I'm hoping for some feedback on this.
2017-02-21 23:12:15 -08:00
hackerkid
10324ba592 Change reaction button color when user reacts.
This makes it easy to see whether you were one of the people who
reacted to a give message.
2017-02-21 23:09:46 -08:00
Ayush Jain
455c1919fc Add customizable invite-new-user text.
This makes life a lot easier for people inviting users to a new Zulip
organization, since they can give some form of context now.

Modified by tabbott to clean up CSS, backend code flow, and improve
the formatting of the emails.

Fixes: #1409.
2017-02-21 22:35:01 -08:00
Tim Abbott
cf96b1b873 generate_realm_creation_link: Clean up instructions. 2017-02-21 20:19:16 -08:00
Tim Abbott
51d3ab1cb7 initialize-database: Clean up final instructions.
Fixes #3678.
2017-02-21 20:19:16 -08:00
Tim Abbott
e608f09f73 compose: Remove unnecessary snapshot_message call.
The current logic that we have is as follows:

* If a message is locally echoed, the draft is stored via the locally
rendered message, and that system takes care of it.  So no need to
store it here.

* If the message isn't locally echoed, we don't close the compose box
until, so the content is safe here as well.  It'll be saved as a draft
if the compose box is later closed due to a failure sending.
2017-02-21 19:24:38 -08:00
Tim Abbott
b05145d9d7 casper: Fix flaky 13-user-deactivation casper test.
This block of code:

casper.click('a[href^="#"]');

actually tried to click basically every link on the page, producing
highly undefined behavior.
2017-02-21 15:02:11 -08:00
Tim Abbott
353f969992 test_events: Add missing print_function py3 import. 2017-02-21 14:26:31 -08:00
Steve Howell
192805903d Make events test more robust for apply_events calls.
We now make tests that call EventsRegisterTest.do_test()
explicitly specify whether calls to apply_events() would
change the state of initially fetched data.  Generally
these tests exist to test that logic (as well as verifying
schemas of events), so if they stop testing that logic, it
is usually a broken test.

Some tests are exempted from the check here, because I think
they don't really change state--such as updating messages or
notifications.  You can set state_change_expected to False
for those tests.

For all the tests that deal with flipping boolean flags, I
set their value to False before calling do_test twice now.

For the authentication backends, I mock the settings so that
more backends are "supported" and therefore part of the event
and the fetched state.

Finally, for the bot tests, I make sure to use a bot the user
can access.
2017-02-21 11:43:09 -08:00
Brock Whittaker
021e43356f Replace settings v1 toggle with v2 component toggle.
This replaces the settings toggle which had the same markup as the
current component toggle, but not the same JavaScript, along with
having an issue with inline-block spacing, with the new JS generated
one.
2017-02-21 11:31:00 -08:00
Brock Whittaker
e4008bcf1c Select first toggle tab by default.
The first one is selected by default, so add the class to make it look
visually selected.
2017-02-21 11:30:59 -08:00
Philip Skomorokhov
7a75ed9c4a message_edit: Fix timer text not decrementing.
This fixes a regression introduced in e6369fc, where we simply lost the `--` part.

Fixes #3720.
2017-02-20 21:41:07 -08:00
Tim Abbott
20f9c04ab5 decorator: Add logging data to zulip_login_required.
This fixes an issue that many logged=in pages such as /stats did not
correctly report either the connecting client or the user in server
logs.
2017-02-20 21:15:44 -08:00
Steve Howell
d4206f2f5f Speed up building user sidebar during page load.
We now call activity.build_user_sidebar when we initialize
the user sidebar, which avoids some janky jQuery code
that was intended for partial updates.

With 2000 users in dev, the amount of time to build the sidebar
decreases from 1100ms to 700ms in my tests.  (Times vary a bit,
but it does seem consistently faster now.)
2017-02-20 18:07:01 -08:00
Steve Howell
2aa7d20a51 refactor: Split build_user_sidebar() from update_users().
Activity.update_users() is still used to handle partial
updates of users in the buddy list, but now all the places
that want to re-build the whole widget go through
build_user_sidebar().
2017-02-20 15:53:14 -08:00
Steve Howell
2566a89f81 refactor: Extract activity.set_presence_info(). 2017-02-20 15:02:56 -08:00
vaibhav
8ac4fe1a73 activity.js: Move info_for and get_num_unread.
We are just moving these functions out to the module
level.  They didn't need to be inner functions.
2017-02-20 14:02:57 -08:00
Tim Abbott
f52d812a71 events: Extract apply_event helper.
This mostly just saves us a level of messy indentation.
2017-02-20 11:16:35 -08:00
Tim Abbott
e4fbad95c6 events: Clean up confusing comment about subscribers. 2017-02-20 11:07:09 -08:00
Tim Abbott
dc0f6413f3 events: Fix include_subscribers=False race conditions.
The original include_subscribers implementation did not correctly
update the apply_events code path to avoid adding 'subscribers' dicts
to things.  This corrects that oversight.
2017-02-20 11:07:09 -08:00
Tim Abbott
7a930afa07 events_register: Don't include subscribers in API data by default.
There's a new option, `include_subscribers`, that controls whether the
API sends down subscriber data for the various streams you are
subscribed to.

This has significant performance savings for large realms with naive
clients, and saves a bunch of bandwidth as well.
2017-02-20 11:07:09 -08:00
Tim Abbott
1cbc86499e events_register: Eliminate unnecessary api_events_register wrapper. 2017-02-20 11:07:09 -08:00
chao1995
b3119b0d67 left-sidebar: Sort pinned streams by lowercase stream name.
The pinned streams were sorted in alphabetic order (i.e. Verona appears
before devel). The reason is that after we plucked pinned streams out from
stream_data.subscribed_streams(), we didn't sort them again, so they
remained in the alphabetic order used in stream_data.

However, we did sort unpinned streams explicitly by using custom compare
function in stream_list.js (by default sort by lowercase stream name,
but when there are more than 40 subscribed streams, sort active streams
first). That's why this issue only relates to pinned streams.

Changes were made to sort pinned streams by lowercase stream name, always,
whether they are active or not (different from unpinned streams).

Tests were added to ensure this overall sort order is correct, i.e.

1. pinned streams are always sorted by lowercase stream name.
2. pinned streams are always before unpinned streams.
3. unpinned streams are sorted by lowercase stream name, if there are more
   than 40 subscribed streams, sort active streams at the top, among active
   and inactive streams, still sorted by lowercase stream name.

Fixes #3701
2017-02-20 10:46:05 -08:00
Tim Abbott
bd1d545a5a travis: Update to handle postgres changes in build env. 2017-02-20 10:44:22 -08:00
vaibhav
35c1272525 Include stream description matches in filter results.
User search for streams will now return results where the stream
description (but not the stream name) include the string in the
user query.

The filtering process first obtains the streams whose names match the
user search query, then sorts and displays them. From the remaining
streams, it obtains streams whose description matches the query and
displays them in sorted order after the name match results. Other
streams are not displayed.

Fixes: #2674.
2017-02-20 06:56:59 -08:00
Tim Abbott
306b29d414 travis: Improve debuggability of rabbitmq errors. 2017-02-19 23:44:40 -08:00
Tim Abbott
4f2a2a39f9 travis: Increase the supervisor sleep to 15s for now.
The hope is this will help us investigate failures like
https://travis-ci.org/zulip/zulip/jobs/203335213.
2017-02-19 23:41:42 -08:00
Tim Abbott
b231bf70eb uploads: Remove display_recipient from fetched data.
This fixes a performance regression loading the Zulip homepage.

While it decreases the utility of the display of messages, it's only
so much loss (because the display recipient for PMs was totally broken
anyway).
2017-02-19 22:19:39 -08:00
Tim Abbott
620f1e444e travis: Fix various bugs in new queue worker test.
* Now queue_workers.py sorts queue names and prints them on their own
  line.  Previously it's output was nondeterministic.
* Simplified grep strategy for removing the "test" worker.
2017-02-19 21:17:42 -08:00
Sourav Badami
eaaec4c908 reactions: Fix emoji picker scrollbar overflow issue.
Fixes #3644.
2017-02-19 21:11:39 -08:00
Umair Khan
dbe609d515 testing: Copy code from unittest.TestSuite.run.
This allows us to use setUpClass.
2017-02-19 21:04:06 -08:00
Umair Khan
128beb910b testing: Use TestResult in run_test.
Internally, Django uses TestResult to gather results from testcases.
This commit upgrades the run_test function to use TestResult to compile
result.
2017-02-19 21:04:06 -08:00
Steve Howell
f28158d301 Live-update default streams when deleting streams.
When an admin deactivate a stream, we now remove the
appropriate row from the default streams tables for other
folks viewing default streams in the admin tables.
2017-02-19 18:06:20 -08:00
Steve Howell
6af83e31f6 admin screens: Encapsulate default streams table.
We add a default_streams_table() function that builds an
object encapsulating the defaults streams table in the admin
system.

This function allows us to simplify the click handler code by
closing on row/stream_name rather than picking those values out
of the DOM.
2017-02-19 18:06:20 -08:00
Steve Howell
96fc6f2372 Remove deactivated streams from the DefaultStream model.
If a stream is deactivated, we now remove it from the
DefaultStream model on the back end.
2017-02-19 18:06:20 -08:00
Kartik Maji
1a697b6e02 Add frontend to show message edit history.
Fixes #268.

Modified significantly by tabbott to:
* improve code cleanliness / repetition
* add missing translation tags
* move code into message_edit.js
* correspond with the new backend.
* not display the option for messages only topic-edited
2017-02-19 17:41:06 -08:00
Kartik Maji
0cf6c292d8 Add edit_history of message in update_messages.
Modified by tabbott to not be confused by embed_links edits.
2017-02-19 17:20:48 -08:00
Tim Abbott
98894eb759 edit_history: Reverse the order of edit history list. 2017-02-19 16:47:07 -08:00
Tim Abbott
eadd6fb3c6 message_edit: Include an initial entry in view output.
This makes it super easy for frontend code using this view code to
produce a nice display of the history.

This also fixes an off-by-one error with the timestamps.
2017-02-19 16:46:47 -08:00
Tim Abbott
42cbce9ad6 travis: Add special check for queue processor lists matching. 2017-02-19 16:19:55 -08:00
Tim Abbott
333062f08e nagios: Automate queue list in check-rabbitmq-consumers. 2017-02-19 16:19:55 -08:00
Tim Abbott
d6bbcd2737 travis: Automate updates to production-helper Nagios test.
This list was likely to end up out of date quickly, since it wasn't
documented that you need to update it when adding a queue.  The best
solution is to just not require it to be updated.
2017-02-19 16:19:53 -08:00
Tim Abbott
8da7976058 queues: Add new system for managing rabbitmq per-queue work.
Our lists of rabbitmq queues was likely to end up out of date, since
there was nothing enforcing that the various lists of queues were
correct or the same as each other.
2017-02-19 16:18:37 -08:00
Tim Abbott
aed3632cbb puppet: Convert remaining queue workers to _ style. 2017-02-19 16:18:37 -08:00
Tim Abbott
4b54307d94 puppet: Generate most of main supervisor config with template. 2017-02-19 16:18:37 -08:00
Tim Abbott
ae09d55e46 puppet: Move zulip.conf to be a template file. 2017-02-19 16:18:37 -08:00
Tim Abbott
515340ed00 Add message edit history backend with tests.
Based on work by Kartik Maji in #1204.

This has a few significant changes from the original version:
* We correctly handle filling in data for topic edits
* Has a complete test suite verifying correctness of the logic
* Currently, it doesn't include a special "start" entry

Things we may want to further change include:
* Adding a special "start" entry.
* Reversing the order of the history data returned for clarity.
2017-02-19 16:13:35 -08:00
Tim Abbott
498f6782a2 EditMessageEdit: Add complete test of edit history. 2017-02-19 16:13:35 -08:00
Tim Abbott
976868cf01 message_edit: Store which user edited a given message.
This is important for, in the future, being able to display who edited
the topic of a message if that wasn't the person who originally sent
the message.
2017-02-19 16:13:04 -08:00
Tim Abbott
f1d82af191 Include prev_rendered_content_version in edit events. 2017-02-19 15:23:08 -08:00
Tim Abbott
78b2eaefc9 timerender: Add get_full_time function.
We'll need to do some iteration, but something like this will be
useful for message edit history.
2017-02-19 15:18:22 -08:00
Tim Abbott
6ad883fb61 docs: Update queuing documentation for new templates. 2017-02-19 13:12:34 -08:00
Tim Abbott
34046c1f55 check-rabbitmq-consumers: Add missing embed_links consumer. 2017-02-19 13:12:00 -08:00
Tim Abbott
213af24e47 check-rabbitmq-consumers: Reformat worker_queues list. 2017-02-19 13:12:00 -08:00
Tim Abbott
64898dd0d1 run-dev-queue-processors: Remove dead code. 2017-02-19 13:11:19 -08:00
Feorlen
87429e1ff9 Fix typo in webhook "Create documentation" section. 2017-02-19 10:02:33 -08:00
Tim Abbott
e29663a2b3 compose: Fix behavior hitting enter with the preview area open.
The new behavior is:
(1) If enter-sends is enabled, just send the messsage.
(2) If enter-sends is not enabled, return focus to the compose area.

Based on great work by khantaalaman in #3673.

Fixes #3489.
2017-02-18 23:31:54 -08:00
Tim Abbott
08a7e0db44 render_messages: Fix buggy handling of edit history. 2017-02-18 22:33:26 -08:00
Tim Abbott
0383ff1dfd lint: Fix homeassistant PEP8 violations. 2017-02-18 21:51:14 -08:00
ausDensk
14024963f2 Add a simple Home Assistant integration for Zulip. 2017-02-18 21:18:10 -08:00
Feorlen
0578ad1563 Add an Advanced topics section.
Add a new section after the Hello World walkthrough for additional detail that
doesn't directly apply to this example. Included are discussions on creating
negative tests and handling custom query parameters.

Remaining integration of the material originally for #3478
2017-02-18 21:03:28 -08:00
Feorlen
a97e0f6730 Add detail to the existing Hello World webhook example.
Fill in additonal detail following the existing document structure.
Includes authentication, custom streams, negative tests, and types
of test data and fixtures. Also fix typos and reformat to match the
new integration doc style.

Partial integration of the material originally for #3478
2017-02-18 21:03:28 -08:00
Cynthia Lin
5090de41f2 user docs: Add responsive design. 2017-02-18 20:54:56 -08:00
Tim Abbott
9ac66b0121 test-backend: Update blacklist of covered files based on CI.
After accidentally merging ecadb33fbc
before I go CI input, I discovered that coverage in my development
environment differs from that in CI :(.
2017-02-18 18:52:59 -08:00
Tim Abbott
32bfebeb7a mypy: Fix inconsistencies in use of *args/**kwargs. 2017-02-18 18:39:44 -08:00
Tim Abbott
473c0ee1fe mypy: Remove now-unused type: ignores. 2017-02-18 17:01:01 -08:00
Tim Abbott
ecadb33fbc test-backend: Add 100% test coverage assertions.
This adds an assertion, when `test-backend` is run with `--coverage`,
that we have 100% test coverage on a list of files that we expect to.
There's a whitelist/blacklist, managed in tools/test-backend.

Fixes #3363.
2017-02-18 16:34:40 -08:00
Tim Abbott
1abfdc340a lint-all: Soften check for % comprehensions. 2017-02-18 16:29:47 -08:00
Tim Abbott
b63a8a7880 integrations: Fix mypy error. 2017-02-18 15:29:43 -08:00
Tim Abbott
b30fb37037 Fix URL routing for users with email addresses starting with "me".
Our URL routing previously attempting to segment the /users/ endpoint
namespace into /me (affecting yourself) or /username@domain (affecting
other users) by regular expressions incorrectly, specifically in the
case of email addresses starting with `me`.  This prevented various
admin actions like removing a user as an organization administrator.
2017-02-18 15:26:04 -08:00
Rishi Gupta
e83d69def8 docs: Copyedit docs/chat-zulip-org.html.
Removed the blurb on "#design" since it appears twice.
2017-02-18 15:03:57 -08:00
Tim Abbott
bbecd41376 help: Fix link to index page being present on index page.
Fixes #3613.
2017-02-18 14:59:43 -08:00
Tim Abbott
6ba1cd797b Fix regression in whitespace stripping at the start of messages.
This fixes a regression in 4060a97656,
which incorrectly stripped whitespace at the start of messages as
well.

Fixes #3719.
2017-02-18 14:47:28 -08:00
Cynthia Lin
d75a1b0bfc user docs: Add user guide for *Add an emoji reaction to a message*.
Fixes #3616.
2017-02-18 14:13:57 -08:00
Cynthia Lin
6890f80383 user docs: Fix minor errors in *Star a message*. 2017-02-18 09:21:35 -08:00
Cynthia Lin
3647a6414a user docs: Add"emoji reaction" to Zulip glossary. 2017-02-18 09:21:35 -08:00
Tim Abbott
3ccbc7c114 run-dev: Use a different path for casper test PID file.
This fixes an issue where running the casper tests while a development
server was running would effectively corrupt the PID file.
2017-02-17 16:31:28 -08:00
Steve Howell
b9ec2545bb Simplify and speed up stream deactivation.
This is a fairly risky, invasive change that speeds up
stream deactivation by no longer sending subscription/remove
events for individual subscribers to all of the clients who
care about a stream.  Instead, we let the client handle the
stream deactivation on a coarser level.

The back end changes here are pretty straightforward.

On the front end we handle stream deactivations by removing the
stream (as needed) from the streams sidebar and/or the stream
settings page.  We also remove the stream from the internal data
structures.

There may be some edge cases where live updates don't handle
everything, such as if you are about to compose a message to a
stream that has been deactivated.  These should be rare, as admins
generally deactivate streams that have been dormant, and they
should be recoverable either by getting proper error handling when
you try to send to the stream or via reload.
2017-02-17 15:53:22 -08:00
Steve Howell
465a765cb0 Add stream_data.delete_sub().
(There was a method with the same name before, but it wasn't
being used.  The new version will accept stream_id instead
of name, and we will use it as part of deactivating streams.)
2017-02-17 15:49:43 -08:00
Steve Howell
1722f1e6c4 Extract stream_list.remove_sidebar_row(). 2017-02-17 15:49:43 -08:00
Steve Howell
b215a23456 bug fix: Fix stream deactivation being super slow.
This fix prevents stream deactivation from being basically
un-usable for medium to large sites.  Instead of calling
bulk_remove_subscriptions one at a time for every individual
member of the realm, we call it once for all the users that
care about the stream.  This change makes a huge difference, but
the feature is still a bit clunky, and we should only temporarily
revert to this fix if future, more-invasive fixes have flaws.

Fixes #3631.
2017-02-17 15:48:10 -08:00
Tim Abbott
c61d0a78f4 home: Remove unused get_client import. 2017-02-17 15:35:38 -08:00
Tim Abbott
7a5065da62 views: Stop hardcoding the 'website' client for the / endpoint.
We were apparently incorrectly harcdoding the client for the main
logged-in site loading to website, rather than using the existing
logic that could sort out the desktop apps.
2017-02-17 15:20:42 -08:00
Tim Abbott
8487a24a6c socket: Hardcode website message sender for fake messages. 2017-02-17 15:20:32 -08:00
Tim Abbott
f105e8270d compose: Fix hardcoding of 'website' client.
We already do detection of the client on the backend based on
User-Agent and the fact that it's a JSON view, which is pretty safe.
This fixes an issue where the server was not treating the Electron app
as its own client.
2017-02-17 15:20:32 -08:00
Tim Abbott
9072d3c350 socket: Transmit HTTP_USER_AGENT for websockets sending.
This significantly simplify the logic for our logging process, making
it the case that websockets message sending requests always are logged
as having the exact same client as a normal AJAX request from that
server.
2017-02-17 15:19:21 -08:00
Tim Abbott
c9126e772e decorator: Don't block ZulipElectron name in json views.
This fixes the logging of the ZulipElectron client in server logs.
Message sending is still logged as "website"; that will be fixed soon.
2017-02-17 15:19:10 -08:00
Tim Abbott
2dc553df0a settings: Fix logging settings for Casper tests.
Previously the casper server.log files basically only had tracebacks;
this should help a lot with debuggability of Casper issues.
2017-02-17 15:18:45 -08:00
Tim Abbott
5c911c44d6 MessageSenderWorker: Reformat environment setup. 2017-02-17 15:00:57 -08:00
Umair Khan
a9bc625dda testing: Serialize test_upload.
This commit makes test_upload tests compatible with parallel model.
2017-02-17 12:40:39 -08:00
Umair Khan
b7d22e3308 testing: Isolate test_patch_bot_avatar.
This commit changes test_patch_bot_avatar to upload avatars to a
different directory so that there is no race condition when tests are
run in parallel mode.
2017-02-17 12:18:43 -08:00
Umair Khan
555d5b4dc6 database: Use new name of PostGresql backend. 2017-02-17 12:18:43 -08:00
Brock Whittaker
7f5703a21f Prevent HTML from being pasted into the stream name/description box.
This prevents users from either dragging formatted markup into content
editable boxes or pasting it in. This uses the “input” event rather
than “paste” because “paste” does not have the end result of the
contents whereas “input” does.

This is not a security vulnerability as it may seem. Processing on the
backend sanitizes input if it contains HTML.
2017-02-17 12:01:24 -08:00
Harshit Bansal
3498c01e1b admin: Make restricted to domains checkbox readonly incase of no domains.
If there are no domains then there is no meaning of setting restricted to
domains checkbox and hence it should be disabled.

Fixes: #3436.
2017-02-17 11:55:15 -08:00
Harshit Bansal
21dccaedd1 test_events.py: Add a test for the do_change_realm_alias() function. 2017-02-17 11:55:15 -08:00
Harshit Bansal
fec145fc0c zerver/models.py: Add comments in 'get_realm_by_email_domain()` function.
Add necessary comments explaining our query sequence.
2017-02-17 11:55:15 -08:00
Steve Howell
3e3444848d Remove avatar timestamp logic in the client.
We use to have client-side logic that would append timestamps
or random numbers to avatar URLs to force browsers to
refresh their cache.

We no longer need this now that the back end maintains
versions for avatar changes and puts the version in the URLs.
2017-02-17 10:19:56 -08:00
Steve Howell
ad24133b94 Have functions in lib/avatar.py use avatar versions.
In some cases here we simplify things by calling avatar_url()
instead of get_avatar_url(), when we have a user_profile record
handy.  For other cases we pass in an extra avatar_version
parameter to get_avatar_url(), including from avatar_url().
2017-02-17 10:19:56 -08:00
Steve Howell
3a04831793 Add avatar_version to active_bot_dict_fields. 2017-02-17 10:19:56 -08:00
Steve Howell
65a4eb8ec8 Add sender_avatar_version to message caches.
We will use this in computing avatar URLs.
2017-02-17 10:19:56 -08:00
Adarsh S
3c2c0c67b9 Bump user_profile.avatar_version when we change avatars.
We have a field called user_profile.avatar_version that will
track avatar versions and be used tactically in avatar urls
to get browsers to refresh their caches (in future commits).

This commit bumps the avatar version when we update avatars.

We do this in do_change_avatar_fields(), which was
do_change_avatar_source() before this change.

Adarsh did the initial work here, and Steve Howell (showell) also
made changes.
2017-02-17 10:19:56 -08:00
Feorlen
61d4dbddb8 Set a default value of None for EMAIL_HOST in DEFAULT_SETTINGS.
Fixes #3669
2017-02-17 08:02:03 -08:00
Feorlen
1973360d17 Update comment to suggest Mailgun for EmailAuthBackend SMTP. 2017-02-17 08:02:03 -08:00
Abhijeet Kaur
d2929b04ca Remove triage_message() function from all the contrib-bots.
To make all bots consistent add shared function in bot_lib.py
to check if this bot is called. All bots respond to at-mention of
the bot instead of their specific names.
2017-02-17 06:51:48 -08:00
aakash-cr7
b72262e8ec Add UI for seeing all muted topics in settings page.
Fixes #2322.
2017-02-17 00:10:18 -08:00
paxapy
9a5179c460 Add support for managing and deleting attachments.
Modified substantially by tabbott to fix tons of issues.

Fixes #454.
2017-02-16 23:44:44 -08:00
Tim Abbott
f528af2be0 Cleanup some unnecessary calls of get_active_user_dicts_in_realm. 2017-02-16 23:29:07 -08:00
Tim Abbott
51313b6b29 storage: Fix minifying CSS/JS files with unicode in them.
Previously, this header construction work would fail on Python 2 in
the case that there were unicode characters in the input.
2017-02-16 22:24:14 -08:00
Tim Abbott
d564a76f8e alert_words: Consistently clean whitespace for alert words.
This fixes some gaps in handling of whitespace in alert words.
2017-02-16 21:06:18 -08:00
Raghav Jajodia
c1dfa348a1 alert_words: Trim whitespace around alert words.
"Add a new alert word" box now displays an alert when filled with only spaces.
Fixes #3369
2017-02-16 21:06:18 -08:00
Steve Howell
c2eb2e61f9 Bump provision version to 4.5.
We had some recent upgrades to mypy.
2017-02-16 17:54:44 -08:00
Tommy Ip
abf522adfb Add styling to distinguish bots from human users in message view.
With work by Brock Whittaker and Tim Abbott on rebasing + changing
styling.

Fixes #1107
2017-02-16 17:00:21 -08:00
Tim Abbott
845f7c10e5 docs: tweak markdown manual testing docs a bit. 2017-02-16 16:24:12 -08:00
Yago González
3746a857af docs: Add details about local echo with Markdown. 2017-02-16 16:24:12 -08:00
adnrs96
3361502141 Clean tutorial_subject handlebar to use 4 space indents. 2017-02-16 14:45:09 -08:00
adnrs96
5c2d3dc4b7 Clean tutorial_stream handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
dcc9f8d75b Clean tutorial_reply handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
049bfff463 Clean tutorial_home handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
66fcc75e5d Clean topic_sidebar_actions handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
e331288084 Clean sidebar_private_message_list handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
51d0211372 Clean reaction_popover_content handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
45d3eaff5f Clean new_stream_users handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
71063e806b Clean message_reactions handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
dc9a7e17c5 Clean message_info_popover_title handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
71951b6995 Clean message_info_popover_content handlebar to use 4 space indents. 2017-02-16 14:45:08 -08:00
adnrs96
4a93a7e9d5 Clean group_pms handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
b5507f2de7 Clean bankruptcy_modal handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
65f7ba9861 Clean announce_streams_docs handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
f73df2a882 Clean alert_word_settings_item handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
11c2ef0f49 Clean admin_streams_list handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
a38fe23ea3 Clean admin_filter_list handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
34fd8618e2 Clean admin_emoji_list handlebar to follow 4 space indents. 2017-02-17 03:16:46 +05:30
adnrs96
00dfe80e4d Clean admin_defaults_streans_list handlebar to use 4 space indents. 2017-02-17 03:16:46 +05:30
Tim Abbott
99c0b0e79f Fix favicon notifications issues for messages sent by oneself.
In Zulip, we mark messages that you send to yourself as read if and
only if they were sent from a known client that represents a human
user use case.  The purpose of this logic is to (1) mark messages
humans send as read while (2) still making it convenient to have a bot
that sends messages to yourself for something like Google calendar,
where you actually want to read those messages.

It's possible that we want to move the control for this behavior into
a client-specific flag rather than doing this off User-Agent.

Fixes #3694.
2017-02-16 13:21:43 -08:00
Steve Howell
5f2e320fee Fix test_valid_api_key_if_user_is_on_wrong_subdomain.
This test would fail if settings.RUNNING_INSIDE_TORNADO
was True, which seemed to happen due to other tests changing
that setting, although I did not fully investigate.
2017-02-15 14:57:01 -08:00
adnrs96
e84cf7b6f1 tools: Create HTML pretty printer.
In This commit we extend the work being done by @showell in PR#1778
to develop a tool to pretty print html and our handlebar templates
in order to enforce our style convention of 4 Space indentation in
templates.

This commit introduces following changes:
* Fix Py3 Compatibility.
* Add ability to prettify in cases when html tags are not the
  starting of a line and addition of test cases for it.
* Add ability to lint handlebar tags and add test cases for it.
* Add {{else}} as special case of indent.
* Add test cases in general to testing new tool.

@showell Helped me throughout and reviewed this commit.

Fixes #1778
2017-02-15 07:34:43 -08:00
Steve Howell
10e220f516 Handle email changes in user_events.update_person().
This code isn't active yet, since the back end doesn't send
events yet for email changes.
2017-02-14 23:25:22 -08:00
Steve Howell
4c53ad59f2 Update PM unread counts more dynamically in the client.
When we process messages for unread counts, we now call
people.pm_reply_user_string() to get a string of user ids,
rather than using emails that may have changed since the
message was originally created.
2017-02-14 23:25:22 -08:00
Steve Howell
ed4adc5650 refactor: Simplify people.pm_reply_to().
We now call people.pm_with_user_ids() to avoid some duplicate
code.
2017-02-14 23:25:22 -08:00
Steve Howell
8d3a5e7f02 Add settings.update_email(). 2017-02-14 23:25:22 -08:00
Steve Howell
0bd3af2bc8 Create narrow.update_email(). 2017-02-14 23:25:22 -08:00
Steve Howell
0eeb023a03 Create filter.update_email().
This helper function will help us process email changes.
2017-02-14 23:25:22 -08:00
Tim Abbott
1acaeb2c80 message_edit: Fix broken triggering of markdown help. 2017-02-14 23:22:37 -08:00
Brock Whittaker
ca428cfc24 Fix tab click unresponsiveness.
There is a particular case in which when a user clicks on a tab, then
uses the goto method to go to another, and then clicks on the original
tab again, it will not load the original tab. This is due to the fact
that the goto function that is used to navigate to a tab without
clicking does not set the last_value, therefore leaving a state that is
incorrect and denying a view update in the case that a user performs
the following:

Click B -> Goto A -> Click B

In this case, it saves the last_value as “B” and so when a user clicks
back on “B” it does not trigger any change as it thinks the user is
going from “B” to “B”.
2017-02-14 23:20:38 -08:00
Brock Whittaker
8f444bdff8 Fix scrollbar width overflow issue.
This fixes the issue where scrollbars that take up space (eg. Chrome on
Linux) force the inline-block items to overflow their container and
fall down a line.
2017-02-14 23:20:38 -08:00
Steve Howell
d406d34fe0 Use user_id in admin_user_list.handlebars.
For our user administration, we now primarily work with user ids
that get put into data-user-id attributes.  We still put emails in the
tags to make our Casper tests easy to maintain.

This requires a minor change to the back end to pass down user ids
for the /users endpoint (in get_members_backend).
2017-02-14 23:07:44 -08:00
Umair Khan
c49789778c testing: Use LocMemCache for backend testing.
LocMemCache is not compatible with frontend tests so we only use it
for backend tests. To do that we change the cache backend within
`not CASPER_TESTS` if block.
2017-02-14 21:32:13 -08:00
Umair Khan
5440bc81b2 logging: Add django.template logger. 2017-02-14 21:20:43 -08:00
Feorlen
b2049a3b06 Clarify the install process's use of the root and zulip users.
Fixes #3680.
2017-02-14 20:44:20 -08:00
Yago González
1861f02de7 docs: Minor fixes on Zulip's Markdown. 2017-02-14 20:41:29 -08:00
Brock Whittaker
a2e9572200 Remove "prefer spread" option in ESLint.
This removes the “prefer spread” option which prefers
the (…args) syntax over using Array.prototype.apply. This
however is part of ES6 syntax and is incompatible with
IE*, Opera*, < Safari 8; and old Chrome, FF versions.
2017-02-14 17:01:39 -08:00
Alicja Raszkowska
1cda0a346f docs: Add a resource to code review doc.
Add James J. Porter's article on code review.
2017-02-14 11:32:01 +01:00
Brock Whittaker
2592ea56bb Change portico navbar style.
This changes the portico navbar style to be in the new brand color
scheme along with removing the borders around the bottom nav bar.
2017-02-13 17:02:03 -08:00
Umair Khan
6db4879f9c testing: Clear cache in queries_captured.
This results in a more deterministic result when we count queries.
2017-02-13 14:24:48 -08:00
Tim Abbott
96f044cb78 docs: Encourage participation in chat.zulip.org. 2017-02-12 17:27:20 -08:00
Tim Abbott
fb23d6970e docs: Better describe chat.zulip.org. 2017-02-12 17:16:28 -08:00
Tim Abbott
f603235735 docs: Rename #provision -> #provision help. 2017-02-12 17:08:22 -08:00
Tim Abbott
9df733d035 docs: Rename installation help -> production help. 2017-02-12 17:04:05 -08:00
Tim Abbott
9eaa0472d5 docs: Update links to point to new chat-zulip-org.html. 2017-02-12 16:57:14 -08:00
Tim Abbott
35ab9de53c docs: Document chat.zulip.org. 2017-02-12 16:57:11 -08:00
Tim Abbott
29ae1b4d4d docs: Fix link to formal/information in German guide. 2017-02-12 16:46:53 -08:00
Tim Abbott
a0aa2ca0f2 hotkey: Fix incorrect test for open subscriptions overlay. 2017-02-12 13:29:12 -08:00
Tim Abbott
9322371742 travis: Restructure .travis.yml to be more consistent. 2017-02-12 11:06:31 -08:00
Durga Akhil M u1604vbox
f833f68bfd mute_ui: Add UI for mute on recipient bar.
Like the topic edit pencil icon, the new UI is mostly invisible, but
appears when you hover over the recipient bar.

* Added a tag to hold the mute button in recipient_row.handlebars with
corresponding styling in zulip.css.
* Added an event handler for the mute button in click_handlers.js.

Fixes: #2235.
2017-02-12 00:45:20 -08:00
Igor Tokarev
55cffa1e69 Added keyboard shortcut to edit the last message.
Tweaked significantly by tabbott to update Casper tests, document the
new feature, and fix hotkeys.

Fixes #1147.
2017-02-12 00:29:28 -08:00
Saumya Rawat
dcd9ff642d dev: Fix postgres provision errors with non-postgres-readable homedir.
This fixes an issue where provision would fail if the user's home
directory was setup in such a way that the postgres user couldn't
access it (and thus the `sudo` command here would throw errors about
having a non-readable current working directory).
2017-02-11 23:47:07 -08:00
Saumya Rawat
151d2139ad dev: Clearer postgres error messages in postgres-init-dev-db.
This uses `pg_isready` to provide a clearer error message if postgres
isn't working.

Fixes #2419.
2017-02-11 23:46:56 -08:00
Tim Abbott
dd37f9ab1f help: add :s to hotkeys docs. 2017-02-11 23:19:45 -08:00
Tim Abbott
6ddb625003 help: Clean up hotkeys doc, e.g. using symbols for arrow keys. 2017-02-11 23:19:04 -08:00
Naren Surampudi
373c7c8f95 help: Document MacOS specific version of various hotkeys.
Fixes #3577.
2017-02-11 23:18:54 -08:00
Tim Abbott
df7b10b7f2 test_runner: Hackishly fix broken failed status.
Something in c14e981e00 broken test
failures being reported properly; this isn't the right fix but works
and will let us avoid reverting the original change until it can be
fixed properly.
2017-02-11 23:02:47 -08:00
Tim Abbott
b79a66fb71 messages: Fix alignment of message sender names.
Now message senders are vertically aligned with the content, whether
mesasges are /me style status messages or not.

We'll want to do more in the future to move both sender names and
message bodies further towards the avatars, I think, but this is
definitely an improvement.
2017-02-11 23:01:22 -08:00
Tim Abbott
173f988aec single_message: Clean up status message templating.
The original templating for this code was super complicated, due to
what appears to be a misguided effort to share code between the
status_message and non-status-message cases, that really just resulted
in a lot of if statements.
2017-02-11 23:01:22 -08:00
Tim Abbott
5c34c601d9 compose: Trim trailing whitespace in messages.
This should ensure that local echo matches the backend in handling of
unusual input like `/me `.
2017-02-11 23:01:22 -08:00
Tim Abbott
4060a97656 messages: Strip trailing whitespace in message contents.
I dug into why we never did this before, and it turns out we did, but
using `$.trim()` (which removes leading whitespace as well!).  When
removing the `$.trim()` usage.

Fixes #3294.
2017-02-11 23:01:22 -08:00
Robert Hönig
6ee845d027 Add html versions of the invite and signup mails
This commit adds html versions of the invite and signup mails and renames
the existing .txt files to the preferred file extensions '.subject', '.html'
and '.txt'. The html versions of the mails are being sent along with the
text-only versions by the 'send_confirmation' function.
This fixes #3134.
2017-02-11 17:08:57 -08:00
Tim Abbott
680d30adc2 docs: Add comments linking to new events doc. 2017-02-11 16:59:28 -08:00
Tim Abbott
eae125e72f docs: Clarify transifex documentation. 2017-02-11 16:57:50 -08:00
Robert Hönig
cbac3fcd64 Merge German translation docs.
Merge the German translation docs 'general-notes.md' and
'special-terms.md' into one translation guide 'german.md'.
2017-02-11 16:42:57 -08:00
Rafid Aslam
241794c586 Change "Reply" to "Quote and reply" in message popover
Change "Reply" in message popover to "Quote and reply"
which is reply and quotes the selected message.

Fixes #3302.
2017-02-11 14:51:55 -08:00
Rishi Gupta
eee5cb5197 analytics: Add tests for views code. 2017-02-11 14:51:01 -08:00
Rishi Gupta
d6ce017a58 analytics: Minor cleanup of views.py. 2017-02-11 14:51:01 -08:00
Rishi Gupta
480fc0874b analytics: Break ties deterministically in sort_client_labels. 2017-02-11 14:51:01 -08:00
Tommy Ip
c7e33c6c9f optimization: Use Python to test management commands.
The original test was written in shell script which launches a new
django instance for every tests. By doing it in Python, we avoid
the overhead and reduce the test time to <1 second.

Fixes #3620.
2017-02-11 13:48:16 -08:00
Elliott Jin
4092aab620 unread: Refactor to move DOM element updates into UI layer. 2017-02-11 08:36:39 -08:00
Elliott Jin
ba449d7c23 unread: Refactor to move server calls into UI layer. 2017-02-11 08:36:39 -08:00
Elliott Jin
ef7d4e417c unread: Refactor to move bankruptcy modal into UI layer. 2017-02-11 08:36:39 -08:00
Elliott Jin
d233f617dd muting: Refactor to move side effects into UI layer. 2017-02-11 08:36:39 -08:00
Tim Abbott
46226bad21 presence: Fix mypy errors in new feature. 2017-02-10 23:57:28 -08:00
Tim Abbott
eeca69cb4b mypy: Clean up more optional types. 2017-02-10 23:53:44 -08:00
Tim Abbott
aee81b702c add_subscriptions_backend: Cleanup type of principals. 2017-02-10 23:53:44 -08:00
Tim Abbott
c9a782ff75 Simplify zerver/views/users.py:get_stream_name. 2017-02-10 23:53:44 -08:00
Tim Abbott
2bba7755e3 decorator: Improve user agent parsing. 2017-02-10 23:53:44 -08:00
Tim Abbott
bc63407e6a decorator: Cleanup api_key_legacy code readability. 2017-02-10 23:53:44 -08:00
Tim Abbott
b81fd407e8 mypy: Fix several Optional typing errors. 2017-02-10 23:53:44 -08:00
Tim Abbott
6d00d4d2b1 mypy: Clean bugdown use of Optional. 2017-02-10 23:53:44 -08:00
Tim Abbott
e746868375 mypy: Fix optional typing usage in rendering code path. 2017-02-10 23:53:44 -08:00
Tim Abbott
4e20b622ad bugdown: Remove unused height argument to add_a. 2017-02-10 23:53:44 -08:00
Tim Abbott
9f0c1db430 mypy: clean up strict optional errors in upload.py. 2017-02-10 23:53:44 -08:00
Tim Abbott
2140d2963d UserPresence: Cleanup confusing to_presence_dict arguments. 2017-02-10 23:53:44 -08:00
Tim Abbott
1c0f65cbec mypy: Fix some incorrect optional tags. 2017-02-10 23:53:44 -08:00
Tim Abbott
879d8cdca0 mypy: Stop using deprecated --silent-imports. 2017-02-10 23:53:44 -08:00
Tim Abbott
bb5d81281c mypy: Upgrade to new package name and version 0.571.
Fixes #3448.
2017-02-10 23:53:44 -08:00
Tim Abbott
f944ac8902 mypy: Fix incorrect annotation for by_used_time. 2017-02-10 23:53:44 -08:00
Tim Abbott
650469ead6 mypy: Make zerver/lib/ccache.py support python 3. 2017-02-10 23:53:44 -08:00
Tim Abbott
923f4ddd80 models: Remove nullable property from RealmAlias.realm. 2017-02-10 23:53:44 -08:00
Tim Abbott
ffc24e9f66 api: Add bindings for new get_presence endpoint. 2017-02-10 23:52:56 -08:00
Tim Abbott
71af0f7e2e Add endpoint to fetch presence data for a single user.
This is an experimental API subject to its data format being changed.

Fixes #3638.
2017-02-10 23:52:56 -08:00
Tim Abbott
ac8b661a8f presence: Extract get_status_dicts_for_query. 2017-02-10 23:52:56 -08:00
Tim Abbott
080182ad17 populate_db: Fix broken initial presence data.
Apparently, the initial data just set everyone to "API" in a broken way.
2017-02-10 23:52:32 -08:00
Steve Howell
2e07533b4e Add compose.update_email().
When we get notified of an email change and the compose box is
open for PMs, we should update the email in the compose box.
This helper will be useful when we start handling such events.
2017-02-10 21:57:50 -08:00
Steve Howell
f56d3807cc Add people.update_email_in_reply_to() helper.
This will be used for live updating.
2017-02-10 21:57:50 -08:00
Steve Howell
f8d59c8108 Make compose replies for PMs more robust.
We now use user_ids from the message to generate the
reply_to more dynamically.
2017-02-10 21:57:50 -08:00
Steve Howell
37509da20d Display sender's most current email in message popover menu. 2017-02-10 21:57:50 -08:00
Steve Howell
ffd45971de Use user ids when processing recent PMs. 2017-02-10 21:57:50 -08:00
Steve Howell
12c4478a3f Use user ids in JS-side "pm-with" filter.
We now convert our pm-with search operand to a list of user ids
for matching against messages, rather than using emails.  On the
message side we look at user ids from display_recipient.
2017-02-10 21:57:48 -08:00
Brock Whittaker
c2e9690e34 Add line break to prevent image inline-block'ing.
The image in the page will display next in line to the previous
paragraph which is not how it should look. This adds a <br> to
make the image appear to work as a block element and go down to
the next line without corrupting the <ol> it lives within.
2017-02-10 21:46:09 -08:00
Brock Whittaker
993189f2a3 Remove link to /#settings in header.
This removes the linke to /#settings in the "Change your settings"
header at the top of the /help/change-your-settings page.
2017-02-10 21:46:09 -08:00
Brock Whittaker
5f6632c9e9 Add "back to home" button at top of help pages.
This adds a button that will bring a user back to the home
of the help section "/help".
2017-02-10 21:46:09 -08:00
Feorlen
74ca33d015 Describe the WIP PR process in Zulip overview doc.
Add new text in the Ways to contribute section to encourage early PRs.
2017-02-10 21:42:38 -08:00
Tim Abbott
7e8d3d9a46 populate_db: Add --extra-bots option to create extra bots. 2017-02-10 17:40:45 -08:00
saisrivathsa
b867ac3496 Extract zerver/lib/events.py from actions.py with event registration.
This moves do_events_register, fetch_initial_state_data and friends to
a new file.

Modified significantly by tabbott for correctness and to remove unused
imports.

Fixes #3635.
2017-02-10 16:50:43 -08:00
Tim Abbott
0564bebdbe test-migrations: Fix inverted check. 2017-02-10 16:41:04 -08:00
Tim Abbott
1fbc3b508a test-migrations: Switch to --check from deprecated -e. 2017-02-10 16:08:13 -08:00
Umair Khan
c14e981e00 testing: Conform runner to Django architecture.
In Django, TestSuite can contain objects of type TestSuite as well
along with TestCases. This is why the run method of TestSuite is
responsible for iterating over items of TestSuite.

This also gives us access to result object which is used by unittest
to gather information about testcases.
2017-02-10 16:01:43 -08:00
Umair Khan
e5a16ceb0a testing: Use failfast instead of fatal_errors.
`failfast` has the same meaning as `fatal_errors` in Django's test
runner.
2017-02-10 16:01:43 -08:00
Umair Khan
7743f74180 Do not append to INSTRMENTED_DATA directly.
Use append_instrumentation_data to append data to the INSTRUMENTED_DATA.
This gives us a layer of abstraction when we need to add instrumentation
data from other modules e.g. while running tests in parallel mode.
2017-02-10 16:01:43 -08:00
Umair Khan
78768a2ba9 Add process_instrumentation_data function.
This function can be used to perform processing on instrumentation data.
For example, this can be used to send the instrumentation data gathered
in the test suite running in the child process to the parent process for
aggregation.
2017-02-10 16:01:43 -08:00
Umair Khan
00f8239563 Clean code of send_test_email command.
* Derive from sendtestemail command of Django.
* Remove unwanted imported.
* Allow test email to admin and managers.
2017-02-10 16:01:43 -08:00
Umair Khan
ef0d2a4bb5 logging: Use django.server to filter 200 and 304.
Previously, we were monkey patching the runserver command
in zerver/management/commands/rundjango.py for this.
2017-02-10 15:55:17 -08:00
Tim Abbott
85fbdd6b2d emails: Remove old 'Keyboard Shortcuts' capitalization. 2017-02-10 15:18:41 -08:00
Tim Abbott
0e802c574d Fix Linux scrollbar issue in information overlays. 2017-02-10 15:18:41 -08:00
Tim Abbott
ce880b0d0c hotkey: Fix incorrect return value from informational overlays.
In theory, whenever an event is handled, it should return true.
2017-02-10 15:18:41 -08:00
brockwhittaker
642dac27b9 Replace the modal footers with an exit button at top of overlay.
This replaces the bootstrap default modal footers that have a
[data-dismiss] button with an .exit button in the top section of the
overlay that is styled congruently to the current subscriptions page.
2017-02-10 15:18:41 -08:00
brockwhittaker
1a28564ed4 Switch information overlay to key-based toggle.
This switches the overlay to a key based system where it uses the
toggle keys to open the correct modals.
2017-02-10 15:18:41 -08:00
brockwhittaker
2ef8e425d1 Change information overlay to use toggle component.
This switches from a custom tab interface to the toggle component
layout.
2017-02-10 15:18:41 -08:00
brockwhittaker
47a3ce2d35 Seperate information overlay CSS into own file.
This takes the information overlay CSS and moves it from zulip.css to
informational-overlays.css to help separate out isolated components.
2017-02-10 15:18:41 -08:00
Brock Whittaker
1500e93092 Convert overlay modals to unified modal system.
This converts three modals:

1. Markdown Help
2. Keyword Shortcuts
3. Search Operators

Into a system in which they all appear in the same overlay now.
2017-02-10 15:18:41 -08:00
brockwhittaker
c70de3ca83 Refactor components.css toggle to include more than two tabs.
This allows for the toggle component to have more than two option tabs.
2017-02-10 14:43:18 -08:00
brockwhittaker
2ea6eda785 Add keys to components.toggle.
This adds keys — unique non-human identifiers to the toggle component.
2017-02-10 14:43:18 -08:00
brockwhittaker
5fbf7de1cf Add usage notes on the component.toggle mechanism.
This adds usage notes and comments to the component.toggle class
to make it more readable and usable for those who are unaware with
the prototype of the class or how to create a new instance.
2017-02-10 14:43:18 -08:00
Rishi Gupta
19d1fc6223 stats: Pass user data to the frontend for messages sent over time. 2017-02-10 14:41:18 -08:00
Rishi Gupta
68a7f91022 stats: Add a fixed display order to summary charts.
API: Adds a "display_order" to the response, which is a suggested order of
importance for the clients or recipient types respectively.

frontend: Changes messages_sent_by_{client,recipient_type} to use a fixed
order for any given user.
2017-02-10 14:41:18 -08:00
Rishi Gupta
cf3ae2eafe stats: Turn messages_sent_by_client into a bar chart.
Also includes a number of changes to messages_sent_by_recipient_type that
were convenient to do at the same time, since the two charts share a lot of
code.
2017-02-10 14:41:18 -08:00
Rishi Gupta
e01f80bf93 stats.js: Move creation of pie traces into the populate functions.
In preparation for turning messages_sent_by_client into a bar chart.
This removes the "pie-specific" pieces from the functions used by
messages_sent_by_{client,type}.
2017-02-10 14:41:18 -08:00
Rishi Gupta
ce89c64f43 stats.js: Move name_map computation to the backend. 2017-02-10 14:41:18 -08:00
Rishi Gupta
8ad7c96382 stats.js: Refactor trace variable to not be list of trace. 2017-02-10 14:41:18 -08:00
Rishi Gupta
a1b1ffe1e4 analytics: Base default views end_time on FillState, not current time. 2017-02-10 14:41:07 -08:00
Rishi Gupta
6ab31d1bac analytics: Move time computation to later in get_chart_data. 2017-02-10 14:40:14 -08:00
Abhijeet Kaur
b22e9a0dbf bug fix: Fix errors in "john" bot in contrib_bots.
Fix outdated code in "john.py" to use "OutputAdapter" module
in Chatterbot. Typecast Chatterbot response to string.
2017-02-10 06:44:03 -08:00
Abhijeet Kaur
87e8d9036f contrib_bots: Restructure bots to follow a consistent structure.
Now all the bots that are stored in contrib_bots are in the
same file/directory format.
The format is specified here #3427. Add tests.py file for encrypt_bot as well.
Fixes #3427.
2017-02-10 06:44:03 -08:00
Tim Abbott
92219aa3dd docs: Add a long document explaining the events system.
This is probably one of Zulip's most important systems, and thus worth
documenting carefully.
2017-02-10 01:17:15 -08:00
Tim Abbott
092bdc7645 docs: Update the casper docs based on recent debugging.
Having just found that a number of our casper tests were buggy because
they were using casper.waitForSelector and fixed those, this seemed
like a good opportunity to update the docs to recommend the selectors
that more faithfully do what developers expect them to.

While I was at it, I tried to make this a bit better organized, though
I think more work could be done on that front.
2017-02-09 23:35:11 -08:00
Tim Abbott
d88c339cc4 casper: Use waitUntilVisible in toggle message editing tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
ed4f2452f2 casper: Use waitUntilVisible in realm creation tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
89c515f8a5 casper: Use waitUntilVisible in narrow tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
5b56fffc3c casper: Use waitUntilVisible in mention tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
8ef3e7cde8 casper: Use waitUntilVisible in editing tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
54883cafcc casper: Use waitUntilVisible in subscriptions tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
2e290d3802 casper: Use waitUntilVisible in navigation tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
532cfab846 casper: Use waitUntilVisible in settings tests. 2017-02-09 23:35:11 -08:00
Tim Abbott
1aac52d685 casper: Use waitUntilVisible in user deactivation tests. 2017-02-09 23:35:10 -08:00
Brock Whittaker
29dbb9e0b4 casper: Use waitUntilVisible and waitWhileVisible in admin tests.
This fixes a potential class of flakiness in the tests where they
interact with parts of the admin UI that aren't actually visible at
the moment via selectors, which probably doesn't test what we intend
to test properly.
2017-02-09 23:35:10 -08:00
Brock Whittaker
1143ed7219 redesign: Change /#settings and /#administration to an overlay.
This also adds a box-shadow to the #deactivate_self_modal so that it
looks similar to the old backdrop.
2017-02-09 23:35:10 -08:00
Tim Abbott
7a76f3dcc8 settings: Redesign the account settings template.
This is technically part of the settings page redesign in the next
commit, but it's probably useful to keep separate, since it touches
totally different code.
2017-02-09 23:33:28 -08:00
Tim Abbott
708c034d93 casper: Extract 13-user-deactivation.js from 10-admin.js.
For some reason, this section of tests basically totally breaks
whatever test runs after it.  To minimize the impact of that problem,
we move it to a separate file.
2017-02-09 23:32:37 -08:00
Tim Abbott
d69c40eb75 casper: Clean up some admin casper tests.
This adds missing casper.then(), some waits for relevant selectors,
and tightens some of the selectors to be more precise.
2017-02-09 23:32:26 -08:00
Brock Whittaker
2dd36aa422 Make subscriptions page responsive.
This makes the subscriptions page responsive by having the settings tab
slide over when a user taps on a stream, giving almost the whole screen
to view the settings.
2017-02-09 14:01:00 -08:00
Abhijeet Kaur
ef72cf5c7c bug fix: Fix wikipedia bot in case no results are found.
Incorrect Index access in wikipedia.py resulted in IndexError and
wikipedia bot to crash for few queries. This causes the bug to be fixed.
Replaced url to avoid 2 redirects and enhance performance.
Fixes: #3508.
2017-02-09 12:20:51 -08:00
Tim Abbott
699257c3bf casper: Extract extended editing tests out of 10-admin.js.
The casper test file 10-admin.js had gotten to be super huge, so a
split is a good idea regardless, but this should also make quaranteen
for tests broken by the settings redesign more manageable.
2017-02-09 00:53:24 -08:00
Tim Abbott
4857f3c2d2 casper: Use casper.then consistently in realm filters tests. 2017-02-09 00:34:56 -08:00
Tim Abbott
26ae2a69a9 casper: Clean up default stream tests a bit more.
This users casper.then in a more reasonable way, and also moves the
stream_name definition to the section where it's used.
2017-02-09 00:34:04 -08:00
Tim Abbott
b8df71c360 subs: Use antialiased fonts in subscriptions page. 2017-02-08 23:28:11 -08:00
Tim Abbott
0aa07b9d0f subs: Improve transitions styling for subscriptions page. 2017-02-08 23:28:10 -08:00
Tim Abbott
64ec7e236d settings: Add missing data-name for auth methods template. 2017-02-08 23:21:21 -08:00
Tim Abbott
febfb1844d settings: Move auth methods template to settings/ subdirectory. 2017-02-08 23:21:21 -08:00
Tim Abbott
09fad19111 settings: Apply new-style to all settings sections. 2017-02-08 23:14:13 -08:00
Tim Abbott
02c8ea729b settings: Reindent settings_tab.handlebars to 4-space. 2017-02-08 23:13:10 -08:00
Tim Abbott
6aea77403d settings: Add data-name entries for administration pages. 2017-02-08 23:11:31 -08:00
Tim Abbott
72ff55db2f help: Fix capitalization of various menu items. 2017-02-08 23:07:14 -08:00
Tim Abbott
1c8d17b7c9 settings: Extract deactivation-user-modal.handlebars. 2017-02-08 22:53:36 -08:00
Tim Abbott
a28bb77b51 settings: Extract deactivation-stream-modal.handlebars. 2017-02-08 22:53:36 -08:00
Tim Abbott
d9b63dd97c settings: Extract realm-domains-modal.handlebars. 2017-02-08 22:53:36 -08:00
Harshit Bansal
8ae54ddb99 actions.py: restricted_to_domain should be False if there are no aliases.
Having `restricted_to_domain` set to True if there are no more aliases
left means the user is either confused or forgot to set it to False. It
should be set to False automatically when the last alias is deleted.
2017-02-08 22:14:43 -08:00
Harshit Bansal
7d10cbc32b Add RealmAlias.allow_subdomains to model, frontend, and API.
Includes a database migration.

Fixes #1868.
2017-02-08 22:03:27 -08:00
Rishi Gupta
a16c48f0c4 actions.py: Change do_remove_realm_alias to take a RealmAlias.
Ensures that this function doesn't throw an error / prevents putting in an
incorrect realm or domain argument.
2017-02-08 21:15:28 -08:00
Tim Abbott
0c363dffca lint: Ban use of deprecated assertEquals. 2017-02-08 16:38:43 -08:00
Kouhei Sutou
a2d935a2ee puppet: Fix PostgreSQL user to create PGroonga extension
"root" user isn't a PostgreSQL administrator. "postgres" is a PostgreSQL
administrator.
2017-02-08 12:57:56 -08:00
Tim Abbott
609082c475 puppet: Remove hardcoding of /root/zulip from puppet path.
This is an important prerequisite to being able to remove dependence
on the /root/zulip symlink altogether.
2017-02-08 11:13:19 -08:00
Elliott Jin
0e0584aeaa muting: Fix calling update_unread_counts in a loop.
Previously, set_muted_topics was calling update_unread_counts once for each
topic in the input; this results in poor performance when there is a large
number of muted topics.

Fixes: #3605
2017-02-08 11:13:19 -08:00
Tim Abbott
fa8045a484 puppet: Add websockets Nagios test to configuration.
Since browser clients send messages via websockets and not the API,
this is an important element in making sure mission-critical Zulip
functionality is working.
2017-02-08 11:13:19 -08:00
Tim Abbott
8db13d0bb9 check_send_receive_time: Use a different state file for websockets.
Otherwise, the two Nagios checks will fight over the same state file
if both are in use.
2017-02-08 11:13:19 -08:00
Kouhei Sutou
5764054bbb docs: Fix markup issue in pgroonga docs. 2017-02-08 10:17:23 -08:00
Umair Khan
c585fa6eb4 change-email: Delete display recipient cache. 2017-02-07 21:49:31 -08:00
Rishi Gupta
677b9e1ec6 stats: Preserve visibility of traces when changing aggregations.
In messages_sent_over_time. Previously, every aggregation kept its own state
regarding which of {Humans, Bots} was showing.
2017-02-07 21:31:34 -08:00
Rishi Gupta
22df58289f stats.js: Fix round_to_percentages when percentage is 100.
Fixes bug introduced in 9901128.
2017-02-07 21:31:34 -08:00
Tim Abbott
84b18f865a users: Verify full names explicitly in account registration.
I believe this completes the project of ensuring that our recent work
on limiting what characters can appears in users' full names covers
the entire codebase.
2017-02-07 20:20:32 -08:00
Tim Abbott
56cecc4891 users: Verify full names explicitly in user creation.
This fixes an issue where users could be created with an invalid name
(introduced only a couple commits ago when we added character set
restrictions).
2017-02-07 19:54:30 -08:00
Tim Abbott
2283b5fc91 users: Consolidate name change enforcement logic.
This has the side effect of fixing an issue where one could edit a
bot to have an invalid name.
2017-02-07 19:45:21 -08:00
Ritwik Srinivas
74b68f6bbc Adds banned characters in name function
Disallows you from putting the characters @, *, `, and > and " in
your name. Added test cases similar to the MAX_NAME_LENGTH check

Copied initial code from:
https://github.com/zulip/zulip/pull/2473
2017-02-07 19:31:14 -08:00
Jackson
dcca54e8a9 integrations: Add Greenhouse integration. 2017-02-07 19:08:35 -08:00
Rishi Gupta
18508ca02c stats.js: Clean up code for the number of users chart. 2017-02-07 18:55:35 -08:00
Rishi Gupta
ac42ad0322 stats.js: Replace font and button colors with variables. 2017-02-07 18:55:35 -08:00
Rishi Gupta
5f2c70c61f stats.js: Refactor code for the two pie charts.
Also fixes a bug where we didn't probably update the labels when clicking on
the Me/Everyone/10/30/Cumulative buttons.
2017-02-07 18:55:35 -08:00
Rishi Gupta
9901128b33 stats.js: Change how we set the precision for percentages close to 100%. 2017-02-07 18:55:35 -08:00
Rishi Gupta
5f7cb9db16 stats.js: Reorder code to match the order of the charts on /stats. 2017-02-07 18:55:35 -08:00
Rishi Gupta
796ac7bfe6 stats.js: Remove the throw_error helper function. 2017-02-07 18:55:35 -08:00
Umair Khan
41aa07adb6 change-email: Delete email caches on email change. 2017-02-07 18:43:26 -08:00
Umair Khan
f4b242e707 Add time validation for email confirmations.
Adds a function which returns the number of days for which
a confirmation link will remain valid. This function can be
overridden by derived classes to provide a different value.
2017-02-07 18:43:26 -08:00
hackerkid
8b2d4f150a Vagrantfile: Add support for a custom post-provision script.
Documentation tweaked by tabbott.

Fixes #3108.
2017-02-07 18:38:07 -08:00
Tim Abbott
cf4faf6598 docs: Clarify that non-webhook integrations need documentation too. 2017-02-07 18:24:35 -08:00
Feorlen
78b9b83650 Create new webhook walkthrough page from the integration guide.
Breaks out the Hello World example to create a new
webhook-walkthrough.md. Includes minor edits so the two docs
read well. Adds the new page, "Webhook walkthrough", to the TOC.

Fixes #3498
2017-02-07 18:22:31 -08:00
Feorlen
676f0ad63f Add WordPress webhook.
Adds a new webhook integration for WordPress blogs. Both WordPress.com
and self-installed blogs are supported, with minor differences that
are described in the documentation. It creates a new message for each
action, the stream and topic may be specified or use default values.

WordPress actions supported:

publish_post:  a new blog post was published
publish_page:  a new page was published
user_register: a new user account was created
wp_login:      a user logged in

Notes: comment_post only provides the id of the parent post, not title
or link, so was not included. On further testing, I found edit_post is
not very practical, it also fires while a new post is being written, and
when posts are deleted. (I think it tracks drafts too.) I've removed it,
as it seems more confusing than useful.

Fixes #3245
2017-02-07 18:14:31 -08:00
Steve Howell
e6bcc01c33 email -> id: Make browser's filter for "sender" more robust. 2017-02-07 17:37:05 -08:00
Steve Howell
64125a76e2 Use data-user-id for message popover menu. 2017-02-07 17:37:05 -08:00
Steve Howell
ae850fdeb4 Use message.sender_id to create URLs in message popover. 2017-02-07 17:37:05 -08:00
Steve Howell
44f155e7b2 Generate message.pm_with_url more directly from ids.
We have added people.pm_with_url(message), which computes a
PM url from a private message using user ids rather than emails.

We call this in add_message_metadata(), since the slugs will
be valid even if emails change, so we don't need to compute
them on the fly during message rendering.
2017-02-07 17:37:05 -08:00
Harshit Bansal
8ed0e09c1f subs.js: Make redraw_privacy_related_stuff() a global function. 2017-02-07 17:02:16 -08:00
Rishi Gupta
e0cb009f1b analytics: Refactor and clean up messages_sent_over_time. 2017-02-07 15:35:43 -08:00
Rishi Gupta
3c692684a0 analytics: Move stats.js out of portico/.
stats.js is a logged-in view.
2017-02-07 15:35:43 -08:00
Tim Abbott
cf87f7cd38 find_team: Automatically focus the target input box. 2017-02-07 15:29:51 -08:00
Tim Abbott
92979e3aac find_team: Show development environment email reminder. 2017-02-07 15:29:38 -08:00
kpdp
cda7faee83 compose: Fix the compose box not resizing when restoring drafts.
Fixes #3592.
2017-02-07 14:41:44 -08:00
Elliott Jin
9b854c62bc search_suggestion: Suggest multiple people in pm-with searches.
Currently, searching for group private messages requires typing each
person's email individually.  This change improves the typeahead
suggestions for group `pm-with` searches by suggesting additional people
whenever a comma is entered.

Fixes: #3575
2017-02-07 14:13:29 -08:00
Tim Abbott
7badc39b02 reactions: Fix exceptions reacting to locally echoed messages.
Previously, we were incorrectly not updating the data-message-id used
in the .message_reactions section to use the final ID when
echo.reify_id was called.

This meant in particular that if someone else reacted to a message you
sent, and you clicked it to share the reaction, you'd get an exception.
2017-02-07 14:13:29 -08:00
Tim Abbott
d98c19ca98 lint: Include pep8 checks in pre-commit hook. 2017-02-07 13:22:01 -08:00
Tim Abbott
20096dfe0d lint: fix PEP8 issue with logging_handlers.py. 2017-02-07 13:22:01 -08:00
Eklavya Sharma
de6884c406 Change True to 'True' in requests.get params.
According to stubs from mypy 0.4.7 onwards, `requests.get` takes
a parameter `params` of type `Dict[AnyStr, AnyStr]` where `AnyStr`
can be either bytes or text.  Actually, requests can accept values
of other types in dicts too but it casts them to a string type.

So to avoid type checking error messages, change `True` to `'True'`.
2017-02-07 12:55:25 -08:00
Tim Abbott
ba5f454be5 puppet: Extract zulip::analytics.
I'm not altogether happy with this (a better solution would be
database-level locking), but I think it solves the immediate problem
of folks with 2 servers being very likely to run analytics on both of
them.
2017-02-07 12:29:15 -08:00
Tim Abbott
f79bced276 logging: Fix recursive exceptions with too large files.
This resolves another new exception in Django 1.10 that now can happen
in our error reporting code path.
2017-02-07 12:28:54 -08:00
Tim Abbott
1005d70ff5 update-prod-static: Fix incorrect ordering of venv setup code.
We should check if we succeeded in using a venv only after we've
actually setup sys.path to use it.
2017-02-07 11:49:31 -08:00
Tim Abbott
b809646854 Add release notes from Zulip Server 1.5.1.
Also update version.py to reflect that everything in 1.5.1 is in this
branch.
2017-02-07 11:40:49 -08:00
Tim Abbott
ec52322ae1 stats: Include Zulip and realm name in heading. 2017-02-07 11:22:57 -08:00
Tim Abbott
ac5c505d3c analytics: Make page-content full height. 2017-02-07 11:17:16 -08:00
Rishi Gupta
a99f5ca066 analytics: Update bar colors on message_sent_over_time. 2017-02-07 11:07:51 -08:00
Rishi Gupta
cd2205ac94 analytics: Remove portico header and footer from stats.html. 2017-02-07 10:49:57 -08:00
Tim Abbott
31d4f99573 upgrade: Stop trying to copy node_modules out of tarballs.
Now that we no longer use node_modules at all in production (it's only
used to generate static assets), we don't include `node_modules` in
the production tarballs, and thus we shouldn't attempt to copy
`node_modules` out of the production tarballs when installing.

Fixes a regression introduced in
d71f2e7b9b.
2017-02-07 10:39:31 -08:00
Tim Abbott
fee394f7b6 roadmap: Mark a bunch of projects as completed. 2017-02-07 10:12:01 -08:00
Rohitt Vashishtha
7a174791f1 api: Add support for Environment Variables.
This adds support for controlling the basic configuration (user, API
key, etc.) of the Zulip API bindings via environment variables.

Fixes #3364.

Tweaked by tabbott to update variable names and document in README.md.
2017-02-06 22:56:59 -08:00
khantaalaman
ee0b16b1ef Update Font Awesome to version 4.7.0.
Fixes #3329.
2017-02-06 22:45:02 -08:00
Steve Howell
5b8e217bf4 Add people.update_email().
The function people.update_email() is not yet connected
to anything, but it sets the stage for upcoming changes.

When emails get updated, fundamentally we just update
the appropriate person object and add a new key to
people_dict.  We sort of get a shim for free--old email
lookups will continue to work--but we add blueslip warnings
for stale lookups.
2017-02-06 22:38:22 -08:00
Steve Howell
0555970fae message_store: Populate sender_email based on people.js.
Messages that come to us from the server may have an out
of date sender email, so we use message.sender_id and
people.js to get the current email.
2017-02-06 22:38:22 -08:00
Steve Howell
a8f706b1b5 refactor: Use user_id as key for people.realm_people_dict. 2017-02-06 22:38:22 -08:00
Steve Howell
2ed85263c8 refactor: Use user_id as key for people.cross_realm_dict. 2017-02-06 22:38:22 -08:00
Steve Howell
955b85f515 Use user_id to check if a message has a new person.
This prepares us for the upcoming ability to update
emails.
2017-02-06 22:38:22 -08:00
Steve Howell
d01493bc42 refactor: Use user_id as key for pm_recipient_count.
We now key people.pm_recipient_count by user_id, which makes
one less dictionary that we'll need to update when we support
email updates.
2017-02-06 22:38:22 -08:00
Steve Howell
08bc69f8af huddles: Calculate huddle strings more robustly.
We now build huddle strings used in activity.js from
user ids in message.display_recipient.
2017-02-06 22:38:22 -08:00
Eklavya Sharma
dd0e1f6a4c Use correct string type in boto function parameters.
boto's stubs have been updated in mypy 0.4.7, which has given us
more information about what type of strings are expected as
parameters in various functions.
2017-02-06 22:37:37 -08:00
Eklavya Sharma
415ce9c312 zerver/lib/test_helpers.py: Wrap function in lambda.
Wrap `list.append` in a lambda before assigning it to
event_queue.process_notification to prevent errors when
event_queue.process_notification is used with keyword arguments.

This also removes an error message by mypy 0.4.7.
2017-02-06 22:35:35 -08:00
Eklavya Sharma
b7635db1e4 Replace 'type' with 'Type[BaseException]'.
This strengthens type checking and helps switch over to mypy 0.4.7.
2017-02-06 22:34:01 -08:00
Eklavya Sharma
0badbbf0e2 Type annotate a variable to prevent future errors.
In zerver.tests.test_decorators.test_check_dict, the variable
'keys' has to be explicitly annotated to pass mypy 0.4.7.
See https://github.com/python/mypy/issues/2777 for more info.
2017-02-06 22:34:01 -08:00
Harshit Bansal
50800d4993 Refactor: De-duplicate the message rendering code in message_list_view.js.
Extract the duplicated message template rendering code in
message_list_view.js to `_get_message_template()` helper function.
2017-02-06 22:30:50 -08:00
Harshit Bansal
8350866406 popovers: Rename data-msgid to data-message-id.
Rename the `data-msgid` to `data-message-id` to match the style of our
other data objects.
2017-02-06 22:30:50 -08:00
sinwar
71247048b4 bots: Use requests instead of unirest for Yoda bot.
Fixes #3500.
2017-02-06 22:07:38 -08:00
Harshit Bansal
9f67f1ada7 DevAuthBackend: Improve the query for dev users.
This changes the query for DevAuthBackend so that the shakespearian
users are not omitted while limiting the number of extra users to be
rendered to something reasonable.

Fixes: #3578.
2017-02-06 21:59:31 -08:00
sinwar
eab355b0cd tools: Create more consistent checks for venv.
This helps make the Zulip development environment somewhat more robust
to new contributors, since it will give them a nice warning if they
try running any of our development tools outside the Zulip virtualenv.

Fixes #3468.
2017-02-06 21:50:32 -08:00
Tim Abbott
b6986d48c7 version: update ZULIP_VERSION to show it's a git version. 2017-02-06 21:46:19 -08:00
2026 changed files with 123016 additions and 56985 deletions

View File

@@ -6,7 +6,7 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.{sh,py,js, json,yml,xml, css, md,markdown, handlebars,html}]
[*.{sh,py,js,json,yml,xml,css,md,markdown,handlebars,html}]
indent_style = space
indent_size = 4

View File

@@ -1,3 +1,3 @@
static/js/bundle.js
static/js/blueslip.js
puppet/zulip_ops/files/statsd/local.js
static/webpack-bundles

View File

@@ -14,25 +14,56 @@
"Dropbox": false,
"SockJS": false,
"marked": false,
"moment": false,
"i18n": false,
"DynamicText": false,
"bridge": false,
"page_params": false,
"status_classes": false,
"password_quality": false,
"attachments_ui": false,
"csrf_token": false,
"typeahead_helper": false,
"pygments_data": false,
"popovers": false,
"server_events": false,
"server_events_dispatch": false,
"ui": false,
"ui_report": false,
"ui_util": false,
"lightbox": false,
"stream_color": false,
"people": false,
"navigate": false,
"settings_account": false,
"settings_display": false,
"settings_notifications": false,
"settings_muting": false,
"settings_lab": false,
"settings_bots": false,
"settings_sections": false,
"settings_emoji": false,
"settings_org": false,
"settings_users": false,
"settings_streams": false,
"settings_filters": false,
"settings": false,
"resize": false,
"loading": false,
"typing": false,
"typing_events": false,
"typing_data": false,
"typing_status": false,
"compose": false,
"compose_actions": false,
"compose_state": false,
"compose_fade": false,
"overlays": false,
"stream_create": false,
"stream_edit": false,
"subs": false,
"stream_muting": false,
"stream_events": false,
"timerender": false,
"message_live_update": false,
"message_edit": false,
@@ -40,8 +71,10 @@
"composebox_typeahead": false,
"search": false,
"topic_list": false,
"topic_generator": false,
"gear_menu": false,
"hashchange": false,
"hash_util": false,
"message_list": false,
"Filter": false,
"pointer": false,
@@ -54,28 +87,41 @@
"Socket": false,
"channel": false,
"components": false,
"viewport": false,
"message_viewport": false,
"upload_widget": false,
"avatar": false,
"realm_icon": false,
"feature_flags": false,
"search_suggestion": false,
"referral": false,
"notifications": false,
"message_flags": false,
"bot_data": false,
"stream_sort": false,
"stream_list": false,
"stream_popover": false,
"narrow_state": false,
"narrow": false,
"narrow_state": false,
"admin_sections": false,
"admin": false,
"stream_data": false,
"list_util": false,
"muting": false,
"Dict": false,
"unread": false,
"alert_words_ui": false,
"message_store": false,
"message_util": false,
"message_events": false,
"message_fetch": false,
"favicon": false,
"condense": false,
"list_render": false,
"floating_recipient_bar": false,
"tab_bar": false,
"emoji": false,
"presence": false,
"activity": false,
"invite": false,
"colorspace": false,
@@ -84,15 +130,26 @@
"templates": false,
"alert_words": false,
"fenced_code": false,
"markdown": false,
"echo": false,
"localstorage": false,
"localStorage": false,
"current_msg_list": true,
"home_msg_list": false,
"pm_list": false,
"pm_conversations": false,
"recent_senders": false,
"unread_ui": false,
"unread_ops": false,
"user_events": false,
"Plotly": false,
"emoji_codes": false
"emoji_codes": false,
"drafts": false,
"katex": false,
"Clipboard": false,
"emoji_picker": false,
"hotspots": false,
"compose_ui": false
},
"rules": {
"no-restricted-syntax": 0,
@@ -135,7 +192,6 @@
"no-new-func": "error",
"space-before-function-paren": ["error", { "anonymous": "always", "named": "never", "asyncArrow": "always" }],
"no-param-reassign": 0,
"prefer-spread": "error",
"arrow-spacing": ["error", { "before": true, "after": true }],
"no-alert": 2,
"no-array-constructor": 2,

5
.gitignore vendored
View File

@@ -18,8 +18,11 @@ coverage/
/zproject/dev-secrets.conf
static/js/bundle.js
static/generated/emoji
static/generated/pygments_data.js
static/generated/github-contributors.json
static/locale/language_options.json
static/third/emoji-data
static/webpack-bundles
/node_modules
/staticfiles.json
npm-debug.log
@@ -27,3 +30,5 @@ npm-debug.log
var/*
.vscode/
tools/conf.ini
tools/custom_provision
api/bots/john/assets/var/database.db

13
.gitlint Normal file
View File

@@ -0,0 +1,13 @@
[general]
ignore=title-trailing-punctuation, body-min-length, body-is-missing
extra-path=tools/lib/gitlint-rules.py
[title-match-regex]
regex=^.+\.$
[title-max-length]
line-length=76
[body-max-line-length]
line-length=76

View File

@@ -1,17 +1,31 @@
# See https://zulip.readthedocs.io/en/latest/events-system.html for
# high-level documentation on our Travis CI setup.
dist: trusty
before_install:
- nvm install 0.10
install:
# Disable Travis CI's built-in NVM installation
- mv ~/.nvm ~/.travis-nvm-disabled
# Install coveralls, the library for the code coverage reporting tool we use
- pip install coveralls
# This is the main setup job for the test suite
- tools/travis/setup-$TEST_SUITE
# Clean any virtualenvs that are not in use to avoid our cache
# becoming huge. TODO: Add similar cleanup code for the other caches.
- tools/clean-venv-cache --travis
script:
# We unset GEM_PATH here as a hack to work around Travis CI having
# broken running their system puppet with Ruby. See
# https://travis-ci.org/zulip/zulip/jobs/240120991 for an example traceback.
- unset GEM_PATH
- ./tools/travis/$TEST_SUITE
cache:
- apt: false
- directories:
- $HOME/zulip-venv-cache
- node_modules
- $HOME/zulip-npm-cache
- $HOME/zulip-emoji-cache
- $HOME/node
env:
global:
@@ -20,13 +34,10 @@ env:
- COVERALLS_SERVICE_NAME=travis-pro
- COVERALLS_REPO_TOKEN=hnXUEBKsORKHc8xIENGs9JjktlTb2HKlG
- BOTO_CONFIG=/tmp/nowhere
matrix:
- TEST_SUITE=frontend
- TEST_SUITE=backend
language: python
python:
- "2.7"
- "3.4"
# We run all of our test suites for both Python 2.7 and 3.4, with the
# exception of static analysis, which is just run once (and checks
# against both Python versions).
matrix:
include:
- python: "3.4"
@@ -35,20 +46,31 @@ matrix:
env: TEST_SUITE=production
- python: "2.7"
env: TEST_SUITE=production
# command to run tests
script:
- unset GEM_PATH
- ./tools/travis/$TEST_SUITE
- python: "2.7"
env: TEST_SUITE=frontend
- python: "3.4"
env: TEST_SUITE=frontend
- python: "2.7"
env: TEST_SUITE=backend
- python: "3.4"
env: TEST_SUITE=backend
sudo: required
services:
- docker
addons:
artifacts:
paths:
# Casper debugging data (screenshots, etc.) is super useful for
# debugging test flakes.
- $(ls var/casper/* | tr "\n" ":")
- $(ls /tmp/zulip-test-event-log/* | tr "\n" ":")
postgresql: "9.3"
after_success:
coveralls
notifications:
webhooks: https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN
webhooks:
urls:
- https://coveralls.io/webhook?repo_token=$COVERALLS_REPO_TOKEN
- https://zulip.org/zulipbot/travis
on_success: always
on_failure: always

100
README.md
View File

@@ -17,7 +17,7 @@ previews, group private messages, audible notifications,
missed-message emails, desktop apps, and much more.
Further information on the Zulip project and its features can be found
at https://www.zulip.org.
at <https://www.zulip.org>.
[![Build Status](https://travis-ci.org/zulip/zulip.svg?branch=master)](https://travis-ci.org/zulip/zulip) [![Coverage Status](https://coveralls.io/repos/github/zulip/zulip/badge.svg?branch=master)](https://coveralls.io/github/zulip/zulip?branch=master) [![docs](https://readthedocs.org/projects/zulip/badge/?version=latest)](http://zulip.readthedocs.io/en/latest/) [![Zulip chat](https://img.shields.io/badge/zulip-join_chat-brightgreen.svg)](https://chat.zulip.org)
@@ -25,18 +25,15 @@ at https://www.zulip.org.
There are several places online where folks discuss Zulip.
One of those places is our [public Zulip instance](https://chat.zulip.org/).
You can go through the simple signup process at that link, and then you
will soon be talking to core Zulip developers and other users. To get
help in real time, you will have the best luck finding core developers
roughly between 16:00 UTC and 23:59 UTC. Most questions get a reply
within minutes to a few hours, depending on time of day.
* The primary place is the
[Zulip development community Zulip server](https://zulip.readthedocs.io/en/latest/chat-zulip-org.html).
For Google Summer of Code students and applicants, we have [a mailing
list](https://groups.google.com/forum/#!forum/zulip-gsoc) for help,
questions, and announcements.
* For Google Summer of Code students and applicants, we have
[a mailing list](https://groups.google.com/forum/#!forum/zulip-gsoc)
for help, questions, and announcements. But it's often simpler to
visit chat.zulip.org instead.
We have
* We have
[a public mailing list](https://groups.google.com/forum/#!forum/zulip-devel)
that is currently pretty low traffic because most discussions happen
in our public Zulip instance. We use it to announce Zulip developer
@@ -47,13 +44,14 @@ ask for generic help getting started as a contributor (e.g. because
you want to do Google Summer of Code). The rest of this page covers
how to get involved in the Zulip project in detail.
Zulip also has a [blog](https://blog.zulip.org/).
* Zulip also has a [blog](https://blog.zulip.org/) and
[twitter account](https://twitter.com/zuliposs).
Last but not least, we use [GitHub](https://github.com/zulip/zulip) to
track Zulip-related issues (and store our code, of course).
* Last but not least, we use [GitHub](https://github.com/zulip/zulip)
to track Zulip-related issues (and store our code, of course).
Anybody with a GitHub account should be able to create Issues there
pertaining to bugs or enhancement requests. We also use Pull
Requests as our primary mechanism to receive code contributions.
pertaining to bugs or enhancement requests. We also use Pull Requests
as our primary mechanism to receive code contributions.
The Zulip community has a [Code of Conduct][code-of-conduct].
@@ -68,17 +66,21 @@ installation guide][dev-install].
Zulip in production supports Ubuntu 14.04 Trusty and Ubuntu 16.04
Xenial. Work is ongoing on adding support for additional
platforms. The installation process is documented at
https://zulip.org/server.html and in more detail in [the
<https://zulip.org/server.html> and in more detail in [the
documentation](https://zulip.readthedocs.io/en/latest/prod-install.html).
## Ways to contribute
Zulip welcomes all forms of contributions! The page documents the
Zulip welcomes all forms of contributions! This page documents the
Zulip development process.
* **Pull requests**. Before a pull request can be merged, you need to
sign the [Dropbox Contributor License Agreement][cla]. Also,
please skim our [commit message style guidelines][doc-commit-style].
We encourage early pull requests for work in progress. Prefix the title
of your pull request with `[WIP]` and reference it when asking for
community feedback. When you are ready for final review, remove
the `[WIP]`.
* **Testing**. The Zulip automated tests all run automatically when
you submit a pull request, but you can also run them all in your
@@ -102,10 +104,10 @@ relevant list! Please report any security issues you discover to
zulip-security@googlegroups.com.
* **App codebases**. This repository is for the Zulip server and web
app (including most integrations); the [desktop][], [Android][], and
[iOS][] apps, are separate repositories, as are our [experimental
React Native iOS app][ios-exp] and [alpha Electron desktop
app][electron].
app (including most integrations); the
[React Native Mobile iOS app][ios-exp], [Android app][Android],
[new Electron desktop app][electron], and
[legacy QT-based desktop app][desktop] are all separate repositories.
* **Glue code**. We maintain a [Hubot adapter][hubot-adapter] and several
integrations ([Phabricator][phab], [Jenkins][], [Puppet][], [Redmine][],
@@ -118,6 +120,14 @@ and [Trello][]), plus [node.js API bindings][node], an [isomorphic
[translating documentation][transifex] if you're interested in
contributing!
* **Code Reviews**. Zulip is all about community and helping each
other out. Check out [#code review][code-review] on
[chat.zulip.org](https://zulip.readthedocs.io/en/latest/chat-zulip-org.html)
to help review PRs and give comments on other people's work. Everyone is
welcome to participate, even those new to Zulip! Even just checking out
the code, manually testing it, and posting on whether or not it worked
is valuable.
[cla]: https://opensource.dropbox.com/cla/
[code-of-conduct]: https://zulip.readthedocs.io/en/latest/code-of-conduct.html
[dev-install]: https://zulip.readthedocs.io/en/latest/dev-overview.html
@@ -130,7 +140,6 @@ contributing!
[gh-issues]: https://github.com/zulip/zulip/issues
[desktop]: https://github.com/zulip/zulip-desktop
[android]: https://github.com/zulip/zulip-android
[ios]: https://github.com/zulip/zulip-ios
[ios-exp]: https://github.com/zulip/zulip-mobile
[email-android]: https://groups.google.com/forum/#!forum/zulip-android
[email-ios]: https://groups.google.com/forum/#!forum/zulip-ios
@@ -145,16 +154,27 @@ contributing!
[tsearch]: https://github.com/zulip/tsearch_extras
[transifex]: https://zulip.readthedocs.io/en/latest/translating.html#testing-translations
[z-org]: https://github.com/zulip/zulip.github.io
[code-review]: https://chat.zulip.org/#narrow/stream/code.20review
## Google Summer of Code
We participated in
[GSoC](https://developers.google.com/open-source/gsoc/) last year and
hope to do so again in 2017. For guidance, please read
[GSoC](https://developers.google.com/open-source/gsoc/) in 2016 (with
[great results](https://blog.zulip.org/2016/10/13/static-types-in-python-oh-mypy/))
and are participating in 2017 as well. For guidance, please read
[our GSoC instructions and ideas page](https://github.com/zulip/zulip.github.io/blob/master/gsoc-ideas.md)
and feel free to email
[our GSoC mailing list](https://groups.google.com/forum/#!forum/zulip-gsoc).
**Note**: For GSoC 2017, we will be focused on making our
[React Native app](https://github.com/zulip/zulip-mobile) better
rather than developing the
[Java Android app](https://github.com/zulip/zulip-android) and
[React Native app](https://github.com/zulip/zulip-mobile) in
parallel. You can review
[our detailed plan](https://github.com/zulip/zulip-android/blob/master/android-strategy.md)
for further details on the motivation and logistics.
## How to get involved with contributing to Zulip
First, subscribe to the Zulip [development discussion mailing
@@ -202,16 +222,25 @@ Another way to find issues in Zulip is to take advantage of our
our issues into areas like admin, compose, emoji, hotkeys, i18n,
onboarding, search, etc. You can see this here:
[https://github.com/zulip/zulip/labels]
<https://github.com/zulip/zulip/labels>
Click on any of the "area:" labels and you will see all the tickets
related to your area of interest.
If you're excited about helping with an open issue, just post on the
conversation thread that you're working on it. You're encouraged to
ask questions on how to best implement or debug your changes -- the
Zulip maintainers are excited to answer questions to help you stay
unblocked and working efficiently.
If you're excited about helping with an open issue, make sure to claim
the issue by commenting the following in the comment section:
"**@zulipbot** claim". **@zulipbot** will assign you to the issue and
label the issue as **in progress**. For more details, check out
[**@zulipbot**](https://github.com/zulip/zulipbot).
You're encouraged to ask questions on how to best implement or debug
your changes -- the Zulip maintainers are excited to answer questions
to help you stay unblocked and working efficiently. It's great to ask
questions in comments on GitHub issues and pull requests, or [on
chat.zulip.org](https://zulip.readthedocs.io/en/latest/chat-zulip-org.html). We'll
direct longer discussions to Zulip chat, but please post a summary of
what you learned from the chat, or link to the conversation, in a
comment on the GitHub issue.
We also welcome suggestions of features that you feel would be
valuable or changes that you feel would make Zulip a better open
@@ -241,9 +270,16 @@ Feedback on how to make this development process more efficient, fun,
and friendly to new contributors is very welcome! Just send an email
to the Zulip Developers list with your thoughts.
When you feel like you have completed your work on an issue, post your
PR to the
[#code review](https://chat.zulip.org/#narrow/stream/code.20review)
stream on [chat.zulip.org](https://zulip.readthedocs.io/en/latest/chat-zulip-org.html).
This is our lightweight process that gives other developers the
opportunity to give you comments and suggestions on your work.
## License
Copyright 2011-2016 Dropbox, Inc. and contributors
Copyright 2011-2017 Dropbox, Inc., Kandra Labs, Inc., and contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

13
Vagrantfile vendored
View File

@@ -99,8 +99,21 @@ set -o pipefail
if [ -d "/sys/fs/selinux" ]; then
sudo mount -o remount,ro /sys/fs/selinux
fi
# Set default locale, this prevents errors if the user has another locale set.
if ! grep -q 'LC_ALL=en_US.UTF-8' /etc/default/locale; then
echo "LC_ALL=en_US.UTF-8" | sudo tee -a /etc/default/locale
fi
# Provision the development environment
ln -nsf /srv/zulip ~/zulip
/srv/zulip/tools/provision
# Run any custom provision hooks the user has configured
if [ -f /srv/zulip/tools/custom_provision ]; then
chmod +x /srv/zulip/tools/custom_provision
/srv/zulip/tools/custom_provision
fi
SCRIPT
config.vm.provision "shell",

View File

@@ -1,19 +1,24 @@
from django.db import connection, models
from django.utils import timezone
from django.conf import settings
from datetime import timedelta, datetime
from django.db import connection, models
from django.db.models import F
from analytics.models import InstallationCount, RealmCount, \
UserCount, StreamCount, BaseCount, FillState, installation_epoch
from zerver.models import Realm, UserProfile, Message, Stream, models
from zerver.lib.timestamp import floor_to_day
UserCount, StreamCount, BaseCount, FillState, Anomaly, installation_epoch, \
last_successful_fill
from zerver.models import Realm, UserProfile, Message, Stream, \
UserActivityInterval, RealmAuditLog, models
from zerver.lib.timestamp import floor_to_day, floor_to_hour, ceiling_to_day, \
ceiling_to_hour
from typing import Any, Optional, Type, Tuple, Text
from typing import Any, Callable, Dict, List, Optional, Text, Tuple, Type, Union
from collections import defaultdict, OrderedDict
from datetime import timedelta, datetime
import logging
import time
## Logging setup ##
log_format = '%(asctime)s %(levelname)-8s %(message)s'
logging.basicConfig(format=log_format)
@@ -25,47 +30,68 @@ logger = logging.getLogger("zulip.management")
logger.setLevel(logging.INFO)
logger.addHandler(file_handler)
# First post office in Boston
MIN_TIME = datetime(1639, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
# You can't subtract timedelta.max from a datetime, so use this instead
TIMEDELTA_MAX = timedelta(days=365*1000)
## Class definitions ##
class CountStat(object):
HOUR = 'hour'
DAY = 'day'
FREQUENCIES = frozenset([HOUR, DAY])
# Allowed intervals are HOUR, DAY, and, GAUGE
GAUGE = 'gauge'
def __init__(self, property, zerver_count_query, filter_args, group_by, frequency, is_gauge):
# type: (str, ZerverCountQuery, Dict[str, bool], Optional[Tuple[models.Model, str]], str, bool) -> None
def __init__(self, property, data_collector, frequency, interval=None):
# type: (str, DataCollector, str, Optional[timedelta]) -> None
self.property = property
self.zerver_count_query = zerver_count_query
self.data_collector = data_collector
# might have to do something different for bitfields
self.filter_args = filter_args
self.group_by = group_by
if frequency not in self.FREQUENCIES:
raise ValueError("Unknown frequency: %s" % (frequency,))
raise AssertionError("Unknown frequency: %s" % (frequency,))
self.frequency = frequency
self.interval = self.GAUGE if is_gauge else frequency
if interval is not None:
self.interval = interval
elif frequency == CountStat.HOUR:
self.interval = timedelta(hours=1)
else: # frequency == CountStat.DAY
self.interval = timedelta(days=1)
def __unicode__(self):
# type: () -> Text
return u"<CountStat: %s>" % (self.property,)
class ZerverCountQuery(object):
def __init__(self, zerver_table, analytics_table, query):
# type: (Type[models.Model], Type[BaseCount], Text) -> None
self.zerver_table = zerver_table
self.analytics_table = analytics_table
self.query = query
class LoggingCountStat(CountStat):
def __init__(self, property, output_table, frequency):
# type: (str, Type[BaseCount], str) -> None
CountStat.__init__(self, property, DataCollector(output_table, None), frequency)
def do_update_fill_state(fill_state, end_time, state):
# type: (FillState, datetime, int) -> None
fill_state.end_time = end_time
fill_state.state = state
fill_state.save()
class DependentCountStat(CountStat):
def __init__(self, property, data_collector, frequency, interval=None, dependencies=[]):
# type: (str, DataCollector, str, Optional[timedelta], List[str]) -> None
CountStat.__init__(self, property, data_collector, frequency, interval=interval)
self.dependencies = dependencies
class DataCollector(object):
def __init__(self, output_table, pull_function):
# type: (Type[BaseCount], Optional[Callable[[str, datetime, datetime], int]]) -> None
self.output_table = output_table
self.pull_function = pull_function
## CountStat-level operations ##
def process_count_stat(stat, fill_to_time):
# type: (CountStat, datetime) -> None
if stat.frequency == CountStat.HOUR:
time_increment = timedelta(hours=1)
elif stat.frequency == CountStat.DAY:
time_increment = timedelta(days=1)
else:
raise AssertionError("Unknown frequency: %s" % (stat.frequency,))
if floor_to_hour(fill_to_time) != fill_to_time:
raise ValueError("fill_to_time must be on an hour boundary: %s" % (fill_to_time,))
if fill_to_time.tzinfo is None:
raise ValueError("fill_to_time must be timezone aware: %s" % (fill_to_time,))
fill_state = FillState.objects.filter(property=stat.property).first()
if fill_state is None:
currently_filled = installation_epoch()
@@ -75,81 +101,88 @@ def process_count_stat(stat, fill_to_time):
logger.info("INITIALIZED %s %s" % (stat.property, currently_filled))
elif fill_state.state == FillState.STARTED:
logger.info("UNDO START %s %s" % (stat.property, fill_state.end_time))
do_delete_count_stat_at_hour(stat, fill_state.end_time)
currently_filled = fill_state.end_time - timedelta(hours = 1)
do_delete_counts_at_hour(stat, fill_state.end_time)
currently_filled = fill_state.end_time - time_increment
do_update_fill_state(fill_state, currently_filled, FillState.DONE)
logger.info("UNDO DONE %s" % (stat.property,))
elif fill_state.state == FillState.DONE:
currently_filled = fill_state.end_time
else:
raise ValueError("Unknown value for FillState.state: %s." % (fill_state.state,))
raise AssertionError("Unknown value for FillState.state: %s." % (fill_state.state,))
currently_filled = currently_filled + timedelta(hours = 1)
if isinstance(stat, DependentCountStat):
for dependency in stat.dependencies:
dependency_fill_time = last_successful_fill(dependency)
if dependency_fill_time is None:
logger.warning("DependentCountStat %s run before dependency %s." %
(stat.property, dependency))
return
fill_to_time = min(fill_to_time, dependency_fill_time)
currently_filled = currently_filled + time_increment
while currently_filled <= fill_to_time:
logger.info("START %s %s %s" % (stat.property, stat.interval, currently_filled))
logger.info("START %s %s" % (stat.property, currently_filled))
start = time.time()
do_update_fill_state(fill_state, currently_filled, FillState.STARTED)
do_fill_count_stat_at_hour(stat, currently_filled)
do_update_fill_state(fill_state, currently_filled, FillState.DONE)
end = time.time()
currently_filled = currently_filled + timedelta(hours = 1)
logger.info("DONE %s %s (%dms)" % (stat.property, stat.interval, (end-start)*1000))
currently_filled = currently_filled + time_increment
logger.info("DONE %s (%dms)" % (stat.property, (end-start)*1000))
# We assume end_time is on an hour boundary, and is timezone aware.
# It is the caller's responsibility to enforce this!
def do_update_fill_state(fill_state, end_time, state):
# type: (FillState, datetime, int) -> None
fill_state.end_time = end_time
fill_state.state = state
fill_state.save()
# We assume end_time is valid (e.g. is on a day or hour boundary as appropriate)
# and is timezone aware. It is the caller's responsibility to enforce this!
def do_fill_count_stat_at_hour(stat, end_time):
# type: (CountStat, datetime) -> None
if stat.frequency == CountStat.DAY and (end_time != floor_to_day(end_time)):
return
if stat.interval == CountStat.HOUR:
start_time = end_time - timedelta(hours = 1)
elif stat.interval == CountStat.DAY:
start_time = end_time - timedelta(days = 1)
else: # stat.interval == CountStat.GAUGE
start_time = MIN_TIME
do_pull_from_zerver(stat, start_time, end_time)
start_time = end_time - stat.interval
if not isinstance(stat, LoggingCountStat):
timer = time.time()
assert(stat.data_collector.pull_function is not None)
rows_added = stat.data_collector.pull_function(stat.property, start_time, end_time)
logger.info("%s run pull_function (%dms/%sr)" %
(stat.property, (time.time()-timer)*1000, rows_added))
do_aggregate_to_summary_table(stat, end_time)
def do_delete_count_stat_at_hour(stat, end_time):
def do_delete_counts_at_hour(stat, end_time):
# type: (CountStat, datetime) -> None
UserCount.objects.filter(property = stat.property, end_time = end_time).delete()
StreamCount.objects.filter(property = stat.property, end_time = end_time).delete()
RealmCount.objects.filter(property = stat.property, end_time = end_time).delete()
InstallationCount.objects.filter(property = stat.property, end_time = end_time).delete()
def do_drop_all_analytics_tables():
# type: () -> None
UserCount.objects.all().delete()
StreamCount.objects.all().delete()
RealmCount.objects.all().delete()
InstallationCount.objects.all().delete()
FillState.objects.all().delete()
if isinstance(stat, LoggingCountStat):
InstallationCount.objects.filter(property=stat.property, end_time=end_time).delete()
if stat.data_collector.output_table in [UserCount, StreamCount]:
RealmCount.objects.filter(property=stat.property, end_time=end_time).delete()
else:
UserCount.objects.filter(property=stat.property, end_time=end_time).delete()
StreamCount.objects.filter(property=stat.property, end_time=end_time).delete()
RealmCount.objects.filter(property=stat.property, end_time=end_time).delete()
InstallationCount.objects.filter(property=stat.property, end_time=end_time).delete()
def do_aggregate_to_summary_table(stat, end_time):
# type: (CountStat, datetime) -> None
cursor = connection.cursor()
# Aggregate into RealmCount
analytics_table = stat.zerver_count_query.analytics_table
if analytics_table in (UserCount, StreamCount):
output_table = stat.data_collector.output_table
if output_table in (UserCount, StreamCount):
realmcount_query = """
INSERT INTO analytics_realmcount
(realm_id, value, property, subgroup, end_time)
SELECT
zerver_realm.id, COALESCE(sum(%(analytics_table)s.value), 0), '%(property)s',
%(analytics_table)s.subgroup, %%(end_time)s
zerver_realm.id, COALESCE(sum(%(output_table)s.value), 0), '%(property)s',
%(output_table)s.subgroup, %%(end_time)s
FROM zerver_realm
JOIN %(analytics_table)s
JOIN %(output_table)s
ON
(
%(analytics_table)s.realm_id = zerver_realm.id AND
%(analytics_table)s.property = '%(property)s' AND
%(analytics_table)s.end_time = %%(end_time)s
)
GROUP BY zerver_realm.id, %(analytics_table)s.subgroup
""" % {'analytics_table': analytics_table._meta.db_table,
zerver_realm.id = %(output_table)s.realm_id
WHERE
%(output_table)s.property = '%(property)s' AND
%(output_table)s.end_time = %%(end_time)s
GROUP BY zerver_realm.id, %(output_table)s.subgroup
""" % {'output_table': output_table._meta.db_table,
'property': stat.property}
start = time.time()
cursor.execute(realmcount_query, {'end_time': end_time})
@@ -164,10 +197,9 @@ def do_aggregate_to_summary_table(stat, end_time):
sum(value), '%(property)s', analytics_realmcount.subgroup, %%(end_time)s
FROM analytics_realmcount
WHERE
(
property = '%(property)s' AND
end_time = %%(end_time)s
) GROUP BY analytics_realmcount.subgroup
GROUP BY analytics_realmcount.subgroup
""" % {'property': stat.property}
start = time.time()
cursor.execute(installationcount_query, {'end_time': end_time})
@@ -175,55 +207,91 @@ def do_aggregate_to_summary_table(stat, end_time):
logger.info("%s InstallationCount aggregation (%dms/%sr)" % (stat.property, (end-start)*1000, cursor.rowcount))
cursor.close()
# This is the only method that hits the prod databases directly.
def do_pull_from_zerver(stat, start_time, end_time):
# type: (CountStat, datetime, datetime) -> None
zerver_table = stat.zerver_count_query.zerver_table._meta.db_table # type: ignore
join_args = ' '.join('AND %s.%s = %s' % (zerver_table, key, value)
for key, value in stat.filter_args.items())
if stat.group_by is None:
## Utility functions called from outside counts.py ##
# called from zerver/lib/actions.py; should not throw any errors
def do_increment_logging_stat(zerver_object, stat, subgroup, event_time, increment=1):
# type: (Union[Realm, UserProfile, Stream], CountStat, Optional[Union[str, int, bool]], datetime, int) -> None
table = stat.data_collector.output_table
if table == RealmCount:
id_args = {'realm': zerver_object}
elif table == UserCount:
id_args = {'realm': zerver_object.realm, 'user': zerver_object}
else: # StreamCount
id_args = {'realm': zerver_object.realm, 'stream': zerver_object}
if stat.frequency == CountStat.DAY:
end_time = ceiling_to_day(event_time)
else: # CountStat.HOUR:
end_time = ceiling_to_hour(event_time)
row, created = table.objects.get_or_create(
property=stat.property, subgroup=subgroup, end_time=end_time,
defaults={'value': increment}, **id_args)
if not created:
row.value = F('value') + increment
row.save(update_fields=['value'])
def do_drop_all_analytics_tables():
# type: () -> None
UserCount.objects.all().delete()
StreamCount.objects.all().delete()
RealmCount.objects.all().delete()
InstallationCount.objects.all().delete()
FillState.objects.all().delete()
Anomaly.objects.all().delete()
## DataCollector-level operations ##
def do_pull_by_sql_query(property, start_time, end_time, query, group_by):
# type: (str, datetime, datetime, str, Optional[Tuple[models.Model, str]]) -> int
if group_by is None:
subgroup = 'NULL'
group_by_clause = ''
else:
subgroup = '%s.%s' % (stat.group_by[0]._meta.db_table, stat.group_by[1])
subgroup = '%s.%s' % (group_by[0]._meta.db_table, group_by[1])
group_by_clause = ', ' + subgroup
# We do string replacement here because passing join_args as a param
# may result in problems when running cursor.execute; we do
# the string formatting prior so that cursor.execute runs it as sql
query_ = stat.zerver_count_query.query % {'zerver_table': zerver_table,
'property': stat.property,
'join_args': join_args,
'subgroup': subgroup,
'group_by_clause': group_by_clause}
# We do string replacement here because cursor.execute will reject a
# group_by_clause given as a param.
# We pass in the datetimes as params to cursor.execute so that we don't have to
# think about how to convert python datetimes to SQL datetimes.
query_ = query % {'property': property, 'subgroup': subgroup,
'group_by_clause': group_by_clause}
cursor = connection.cursor()
start = time.time()
cursor.execute(query_, {'time_start': start_time, 'time_end': end_time})
end = time.time()
logger.info("%s do_pull_from_zerver (%dms/%sr)" % (stat.property, (end-start)*1000, cursor.rowcount))
rowcount = cursor.rowcount
cursor.close()
return rowcount
count_user_by_realm_query = """
INSERT INTO analytics_realmcount
(realm_id, value, property, subgroup, end_time)
SELECT
zerver_realm.id, count(%(zerver_table)s),'%(property)s', %(subgroup)s, %%(time_end)s
FROM zerver_realm
JOIN zerver_userprofile
ON
(
zerver_userprofile.realm_id = zerver_realm.id AND
zerver_userprofile.date_joined >= %%(time_start)s AND
zerver_userprofile.date_joined < %%(time_end)s
%(join_args)s
)
WHERE
zerver_realm.date_created < %%(time_end)s
GROUP BY zerver_realm.id %(group_by_clause)s
"""
zerver_count_user_by_realm = ZerverCountQuery(UserProfile, RealmCount, count_user_by_realm_query)
def sql_data_collector(output_table, query, group_by):
# type: (Type[BaseCount], str, Optional[Tuple[models.Model, str]]) -> DataCollector
def pull_function(property, start_time, end_time):
# type: (str, datetime, datetime) -> int
return do_pull_by_sql_query(property, start_time, end_time, query, group_by)
return DataCollector(output_table, pull_function)
def do_pull_minutes_active(property, start_time, end_time):
# type: (str, datetime, datetime) -> int
user_activity_intervals = UserActivityInterval.objects.filter(
end__gt=start_time, start__lt=end_time
).select_related(
'user_profile'
).values_list(
'user_profile_id', 'user_profile__realm_id', 'start', 'end')
seconds_active = defaultdict(float) # type: Dict[Tuple[int, int], float]
for user_id, realm_id, interval_start, interval_end in user_activity_intervals:
start = max(start_time, interval_start)
end = min(end_time, interval_end)
seconds_active[(user_id, realm_id)] += (end - start).total_seconds()
rows = [UserCount(user_id=ids[0], realm_id=ids[1], property=property,
end_time=end_time, value=int(seconds // 60))
for ids, seconds in seconds_active.items() if seconds >= 60]
UserCount.objects.bulk_create(rows)
return len(rows)
# currently .sender_id is only Message specific thing
count_message_by_user_query = """
INSERT INTO analytics_usercount
(user_id, realm_id, value, property, subgroup, end_time)
@@ -232,17 +300,162 @@ count_message_by_user_query = """
FROM zerver_userprofile
JOIN zerver_message
ON
(
zerver_message.sender_id = zerver_userprofile.id AND
zerver_userprofile.id = zerver_message.sender_id
WHERE
zerver_userprofile.date_joined < %%(time_end)s AND
zerver_message.pub_date >= %%(time_start)s AND
zerver_message.pub_date < %%(time_end)s
%(join_args)s
)
WHERE
zerver_userprofile.date_joined < %%(time_end)s
GROUP BY zerver_userprofile.id %(group_by_clause)s
"""
zerver_count_message_by_user = ZerverCountQuery(Message, UserCount, count_message_by_user_query)
# Note: ignores the group_by / group_by_clause.
count_message_type_by_user_query = """
INSERT INTO analytics_usercount
(realm_id, user_id, value, property, subgroup, end_time)
SELECT realm_id, id, SUM(count) AS value, '%(property)s', message_type, %%(time_end)s
FROM
(
SELECT zerver_userprofile.realm_id, zerver_userprofile.id, count(*),
CASE WHEN
zerver_recipient.type = 1 THEN 'private_message'
WHEN
zerver_recipient.type = 3 THEN 'huddle_message'
WHEN
zerver_stream.invite_only = TRUE THEN 'private_stream'
ELSE 'public_stream'
END
message_type
FROM zerver_userprofile
JOIN zerver_message
ON
zerver_userprofile.id = zerver_message.sender_id AND
zerver_message.pub_date >= %%(time_start)s AND
zerver_message.pub_date < %%(time_end)s
JOIN zerver_recipient
ON
zerver_message.recipient_id = zerver_recipient.id
LEFT JOIN zerver_stream
ON
zerver_recipient.type_id = zerver_stream.id
GROUP BY zerver_userprofile.realm_id, zerver_userprofile.id, zerver_recipient.type, zerver_stream.invite_only
) AS subquery
GROUP BY realm_id, id, message_type
"""
# This query joins to the UserProfile table since all current queries that
# use this also subgroup on UserProfile.is_bot. If in the future there is a
# stat that counts messages by stream and doesn't need the UserProfile
# table, consider writing a new query for efficiency.
count_message_by_stream_query = """
INSERT INTO analytics_streamcount
(stream_id, realm_id, value, property, subgroup, end_time)
SELECT
zerver_stream.id, zerver_stream.realm_id, count(*), '%(property)s', %(subgroup)s, %%(time_end)s
FROM zerver_stream
JOIN zerver_recipient
ON
zerver_stream.id = zerver_recipient.type_id
JOIN zerver_message
ON
zerver_recipient.id = zerver_message.recipient_id
JOIN zerver_userprofile
ON
zerver_message.sender_id = zerver_userprofile.id
WHERE
zerver_stream.date_created < %%(time_end)s AND
zerver_recipient.type = 2 AND
zerver_message.pub_date >= %%(time_start)s AND
zerver_message.pub_date < %%(time_end)s
GROUP BY zerver_stream.id %(group_by_clause)s
"""
# Hardcodes the query needed by active_users:is_bot:day, since that is
# currently the only stat that uses this.
count_user_by_realm_query = """
INSERT INTO analytics_realmcount
(realm_id, value, property, subgroup, end_time)
SELECT
zerver_realm.id, count(*),'%(property)s', %(subgroup)s, %%(time_end)s
FROM zerver_realm
JOIN zerver_userprofile
ON
zerver_realm.id = zerver_userprofile.realm_id
WHERE
zerver_realm.date_created < %%(time_end)s AND
zerver_userprofile.date_joined >= %%(time_start)s AND
zerver_userprofile.date_joined < %%(time_end)s AND
zerver_userprofile.is_active = TRUE
GROUP BY zerver_realm.id %(group_by_clause)s
"""
# Currently hardcodes the query needed for active_users_audit:is_bot:day.
# Assumes that a user cannot have two RealmAuditLog entries with the same event_time and
# event_type in ['user_created', 'user_deactivated', etc].
# In particular, it's important to ensure that migrations don't cause that to happen.
check_realmauditlog_by_user_query = """
INSERT INTO analytics_usercount
(user_id, realm_id, value, property, subgroup, end_time)
SELECT
ral1.modified_user_id, ral1.realm_id, 1, '%(property)s', %(subgroup)s, %%(time_end)s
FROM zerver_realmauditlog ral1
JOIN (
SELECT modified_user_id, max(event_time) AS max_event_time
FROM zerver_realmauditlog
WHERE
event_type in ('user_created', 'user_deactivated', 'user_activated', 'user_reactivated') AND
event_time < %%(time_end)s
GROUP BY modified_user_id
) ral2
ON
ral1.event_time = max_event_time AND
ral1.modified_user_id = ral2.modified_user_id
JOIN zerver_userprofile
ON
ral1.modified_user_id = zerver_userprofile.id
WHERE
ral1.event_type in ('user_created', 'user_activated', 'user_reactivated')
"""
check_useractivityinterval_by_user_query = """
INSERT INTO analytics_usercount
(user_id, realm_id, value, property, subgroup, end_time)
SELECT
zerver_userprofile.id, zerver_userprofile.realm_id, 1, '%(property)s', %(subgroup)s, %%(time_end)s
FROM zerver_userprofile
JOIN zerver_useractivityinterval
ON
zerver_userprofile.id = zerver_useractivityinterval.user_profile_id
WHERE
zerver_useractivityinterval.end >= %%(time_start)s AND
zerver_useractivityinterval.start < %%(time_end)s
GROUP BY zerver_userprofile.id %(group_by_clause)s
"""
count_realm_active_humans_query = """
INSERT INTO analytics_realmcount
(realm_id, value, property, subgroup, end_time)
SELECT
usercount1.realm_id, count(*), '%(property)s', NULL, %%(time_end)s
FROM (
SELECT realm_id, user_id
FROM analytics_usercount
WHERE
property = 'active_users_audit:is_bot:day' AND
subgroup = 'false' AND
end_time = %%(time_end)s
) usercount1
JOIN (
SELECT realm_id, user_id
FROM analytics_usercount
WHERE
property = '15day_actives::day' AND
end_time = %%(time_end)s
) usercount2
ON
usercount1.user_id = usercount2.user_id
GROUP BY usercount1.realm_id
"""
# Currently unused and untested
count_stream_by_realm_query = """
@@ -253,101 +466,71 @@ count_stream_by_realm_query = """
FROM zerver_realm
JOIN zerver_stream
ON
(
zerver_stream.realm_id = zerver_realm.id AND
zerver_realm.id = zerver_stream.realm_id AND
WHERE
zerver_realm.date_created < %%(time_end)s AND
zerver_stream.date_created >= %%(time_start)s AND
zerver_stream.date_created < %%(time_end)s
%(join_args)s
)
WHERE
zerver_realm.date_created < %%(time_end)s
GROUP BY zerver_realm.id %(group_by_clause)s
"""
zerver_count_stream_by_realm = ZerverCountQuery(Stream, RealmCount, count_stream_by_realm_query)
# This query violates the count_X_by_Y_query conventions in several ways. One,
# the X table is not specified by the query name; MessageType is not a zerver
# table. Two, it ignores the subgroup column in the CountStat object; instead,
# it uses 'message_type' from the subquery to fill in the subgroup column.
count_message_type_by_user_query = """
INSERT INTO analytics_usercount
(realm_id, user_id, value, property, subgroup, end_time)
SELECT realm_id, id, SUM(count) AS value, '%(property)s', message_type, %%(time_end)s
FROM
(
SELECT zerver_userprofile.realm_id, zerver_userprofile.id, count(*),
CASE WHEN
zerver_recipient.type != 2 THEN 'private_message'
WHEN
zerver_stream.invite_only = TRUE THEN 'private_stream'
ELSE 'public_stream'
END
message_type
## CountStat declarations ##
FROM zerver_userprofile
JOIN zerver_message
ON
zerver_message.sender_id = zerver_userprofile.id AND
zerver_message.pub_date >= %%(time_start)s AND
zerver_message.pub_date < %%(time_end)s
%(join_args)s
JOIN zerver_recipient
ON
zerver_recipient.id = zerver_message.recipient_id
LEFT JOIN zerver_stream
ON
zerver_stream.id = zerver_recipient.type_id
GROUP BY zerver_userprofile.realm_id, zerver_userprofile.id, zerver_recipient.type, zerver_stream.invite_only
) AS subquery
GROUP BY realm_id, id, message_type
"""
zerver_count_message_type_by_user = ZerverCountQuery(Message, UserCount, count_message_type_by_user_query)
count_stats_ = [
# Messages Sent stats
# Stats that count the number of messages sent in various ways.
# These are also the set of stats that read from the Message table.
# Note that this query also joins to the UserProfile table, since all
# current queries that use this also subgroup on UserProfile.is_bot. If in
# the future there is a query that counts messages by stream and doesn't need
# the UserProfile table, consider writing a new query for efficiency.
count_message_by_stream_query = """
INSERT INTO analytics_streamcount
(stream_id, realm_id, value, property, subgroup, end_time)
SELECT
zerver_stream.id, zerver_stream.realm_id, count(*), '%(property)s', %(subgroup)s, %%(time_end)s
FROM zerver_stream
JOIN zerver_recipient
ON
(
zerver_recipient.type = 2 AND
zerver_stream.id = zerver_recipient.type_id
)
JOIN zerver_message
ON
(
zerver_message.recipient_id = zerver_recipient.id AND
zerver_message.pub_date >= %%(time_start)s AND
zerver_message.pub_date < %%(time_end)s AND
zerver_stream.date_created < %%(time_end)s
%(join_args)s
)
JOIN zerver_userprofile
ON zerver_userprofile.id = zerver_message.sender_id
GROUP BY zerver_stream.id %(group_by_clause)s
"""
zerver_count_message_by_stream = ZerverCountQuery(Message, StreamCount, count_message_by_stream_query)
CountStat('messages_sent:is_bot:hour',
sql_data_collector(UserCount, count_message_by_user_query, (UserProfile, 'is_bot')),
CountStat.HOUR),
CountStat('messages_sent:message_type:day',
sql_data_collector(UserCount, count_message_type_by_user_query, None), CountStat.DAY),
CountStat('messages_sent:client:day',
sql_data_collector(UserCount, count_message_by_user_query, (Message, 'sending_client_id')),
CountStat.DAY),
CountStat('messages_in_stream:is_bot:day',
sql_data_collector(StreamCount, count_message_by_stream_query, (UserProfile, 'is_bot')),
CountStat.DAY),
COUNT_STATS = {
'active_users:is_bot:day': CountStat(
'active_users:is_bot:day', zerver_count_user_by_realm, {'is_active': True},
(UserProfile, 'is_bot'), CountStat.DAY, True),
'messages_sent:is_bot:hour': CountStat(
'messages_sent:is_bot:hour', zerver_count_message_by_user, {},
(UserProfile, 'is_bot'), CountStat.HOUR, False),
'messages_sent:message_type:day': CountStat(
'messages_sent:message_type:day', zerver_count_message_type_by_user, {},
None, CountStat.DAY, False),
'messages_sent:client:day': CountStat(
'messages_sent:client:day', zerver_count_message_by_user, {},
(Message, 'sending_client_id'), CountStat.DAY, False),
'messages_sent_to_stream:is_bot:hour': CountStat(
'messages_sent_to_stream:is_bot', zerver_count_message_by_stream, {},
(UserProfile, 'is_bot'), CountStat.HOUR, False)
}
# Number of Users stats
# Stats that count the number of active users in the UserProfile.is_active sense.
# 'active_users_audit:is_bot:day' is the canonical record of which users were
# active on which days (in the UserProfile.is_active sense).
# Important that this stay a daily stat, so that 'realm_active_humans::day' works as expected.
CountStat('active_users_audit:is_bot:day',
sql_data_collector(UserCount, check_realmauditlog_by_user_query, (UserProfile, 'is_bot')),
CountStat.DAY),
# Sanity check on 'active_users_audit:is_bot:day', and a archetype for future LoggingCountStats.
# In RealmCount, 'active_users_audit:is_bot:day' should be the partial
# sum sequence of 'active_users_log:is_bot:day', for any realm that
# started after the latter stat was introduced.
LoggingCountStat('active_users_log:is_bot:day', RealmCount, CountStat.DAY),
# Another sanity check on 'active_users_audit:is_bot:day'. Is only an
# approximation, e.g. if a user is deactivated between the end of the
# day and when this stat is run, they won't be counted. However, is the
# simplest of the three to inspect by hand.
CountStat('active_users:is_bot:day',
sql_data_collector(RealmCount, count_user_by_realm_query, (UserProfile, 'is_bot')),
CountStat.DAY, interval=TIMEDELTA_MAX),
# User Activity stats
# Stats that measure user activity in the UserActivityInterval sense.
CountStat('15day_actives::day',
sql_data_collector(UserCount, check_useractivityinterval_by_user_query, None),
CountStat.DAY, interval=timedelta(days=15)-UserActivityInterval.MIN_INTERVAL_LENGTH),
CountStat('minutes_active::day', DataCollector(UserCount, do_pull_minutes_active), CountStat.DAY),
# Dependent stats
# Must come after their dependencies.
# Canonical account of the number of active humans in a realm on each day.
DependentCountStat('realm_active_humans::day',
sql_data_collector(RealmCount, count_realm_active_humans_query, None),
CountStat.DAY,
dependencies=['active_users_audit:is_bot:day', '15day_actives::day'])
]
COUNT_STATS = OrderedDict([(stat.property, stat) for stat in count_stats_])

View File

@@ -8,12 +8,13 @@ from analytics.lib.time_utils import time_range
from datetime import datetime
from math import sqrt
from random import gauss, random, seed
from typing import List
from six.moves import range, zip
def generate_time_series_data(days=100, business_hours_base=10, non_business_hours_base=10,
growth=1, autocorrelation=0, spikiness=1, holiday_rate=0,
frequency=CountStat.DAY, is_gauge=False, random_seed=26):
frequency=CountStat.DAY, partial_sum=False, random_seed=26):
# type: (int, float, float, float, float, float, float, str, bool, int) -> List[int]
"""
Generate semi-realistic looking time series data for testing analytics graphs.
@@ -31,7 +32,7 @@ def generate_time_series_data(days=100, business_hours_base=10, non_business_hou
the variance.
holiday_rate -- Fraction of days randomly set to 0, largely for testing how we handle 0s.
frequency -- Should be CountStat.HOUR or CountStat.DAY.
is_gauge -- If True, return partial sum of the series.
partial_sum -- If True, return partial sum of the series.
random_seed -- Seed for random number generator.
"""
if frequency == CountStat.HOUR:
@@ -49,10 +50,10 @@ def generate_time_series_data(days=100, business_hours_base=10, non_business_hou
[24*non_business_hours_base] * 2
holidays = [random() < holiday_rate for i in range(days)]
else:
raise ValueError("Unknown frequency: %s" % (frequency,))
raise AssertionError("Unknown frequency: %s" % (frequency,))
if length < 2:
raise ValueError("Must be generating at least 2 data points. "
"Currently generating %s" % (length,))
raise AssertionError("Must be generating at least 2 data points. "
"Currently generating %s" % (length,))
growth_base = growth ** (1. / (length-1))
values_no_noise = [seasonality[i % len(seasonality)] * (growth_base**i) for i in range(length)]
@@ -63,7 +64,7 @@ def generate_time_series_data(days=100, business_hours_base=10, non_business_hou
values = [0 if holiday else int(v + sqrt(v)*noise_scalar*spikiness)
for v, noise_scalar, holiday in zip(values_no_noise, noise_scalars, holidays)]
if is_gauge:
if partial_sum:
for i in range(1, length):
values[i] = values[i-1] + values[i]
return [max(v, 0) for v in values]

View File

@@ -17,7 +17,7 @@ def time_range(start, end, frequency, min_length):
end = floor_to_day(end)
step = timedelta(days=1)
else:
raise ValueError("Unknown frequency: %s" % (frequency,))
raise AssertionError("Unknown frequency: %s" % (frequency,))
times = []
if min_length is not None:

View File

@@ -2,7 +2,8 @@ from __future__ import absolute_import
from __future__ import print_function
from django.core.management.base import BaseCommand
from typing import Any
from django.utils.timezone import now as timezone_now
from typing import Any, Dict, List
from zerver.models import UserPresence, UserActivity
from zerver.lib.utils import statsd, statsd_key
@@ -18,13 +19,13 @@ class Command(BaseCommand):
def handle(self, *args, **options):
# type: (*Any, **Any) -> None
# Get list of all active users in the last 1 week
cutoff = datetime.now() - timedelta(minutes=30, hours=168)
cutoff = timezone_now() - timedelta(minutes=30, hours=168)
users = UserPresence.objects.select_related().filter(timestamp__gt=cutoff)
# Calculate 10min, 2hrs, 12hrs, 1day, 2 business days (TODO business days), 1 week bucket of stats
hour_buckets = [0.16, 2, 12, 24, 48, 168]
user_info = defaultdict(dict) # type: Dict[str, Dict[float, List[str]]]
user_info = defaultdict(dict) # type: Dict[str, Dict[float, List[str]]]
for last_presence in users:
if last_presence.status == UserPresence.IDLE:
@@ -35,7 +36,7 @@ class Command(BaseCommand):
for bucket in hour_buckets:
if bucket not in user_info[last_presence.user_profile.realm.string_id]:
user_info[last_presence.user_profile.realm.string_id][bucket] = []
if datetime.now(known_active.tzinfo) - known_active < timedelta(hours=bucket):
if timezone_now() - known_active < timedelta(hours=bucket):
user_info[last_presence.user_profile.realm.string_id][bucket].append(last_presence.user_profile.email)
for realm, buckets in user_info.items():
@@ -51,7 +52,7 @@ class Command(BaseCommand):
for bucket in hour_buckets:
if bucket not in user_info[activity.user_profile.realm.string_id]:
user_info[activity.user_profile.realm.string_id][bucket] = []
if datetime.now(activity.last_visit.tzinfo) - activity.last_visit < timedelta(hours=bucket):
if timezone_now() - activity.last_visit < timedelta(hours=bucket):
user_info[activity.user_profile.realm.string_id][bucket].append(activity.user_profile.email)
for realm, buckets in user_info.items():
print("Realm %s" % (realm,))

View File

@@ -6,7 +6,9 @@ import pytz
from optparse import make_option
from typing import Any
from django.core.management.base import BaseCommand, CommandParser
from django.utils.timezone import now as timezone_now
from zerver.lib.statistics import activity_averages_during_day
class Command(BaseCommand):
@@ -20,9 +22,9 @@ class Command(BaseCommand):
def handle(self, *args, **options):
# type: (*Any, **Any) -> None
if options["date"] is None:
date = datetime.datetime.now() - datetime.timedelta(days=1)
date = timezone_now() - datetime.timedelta(days=1)
else:
date = datetime.datetime.strptime(options["date"], "%Y-%m-%d")
date = datetime.datetime.strptime(options["date"], "%Y-%m-%d").replace(tzinfo=pytz.utc)
print("Activity data for", date)
print(activity_averages_during_day(date))
print("Please note that the total registered user count is a total for today")

View File

@@ -1,7 +1,7 @@
from __future__ import absolute_import
from __future__ import print_function
from typing import Any
from typing import Any, Dict
from optparse import make_option
from django.core.management.base import BaseCommand, CommandParser
@@ -17,7 +17,7 @@ def compute_stats(log_level):
logger.setLevel(log_level)
one_week_ago = timestamp_to_datetime(time.time()) - datetime.timedelta(weeks=1)
mit_query = Message.objects.filter(sender__realm__string_id="mit",
mit_query = Message.objects.filter(sender__realm__string_id="zephyr",
recipient__type=Recipient.STREAM,
pub_date__gt=one_week_ago)
for bot_sender_start in ["imap.", "rcmd.", "sys."]:
@@ -30,15 +30,15 @@ def compute_stats(log_level):
"bitcoin@mit.edu", "lp@mit.edu", "clocks@mit.edu",
"root@mit.edu", "nagios@mit.edu",
"www-data|local-realm@mit.edu"])
user_counts = {} # type: Dict[str, Dict[str, int]]
user_counts = {} # type: Dict[str, Dict[str, int]]
for m in mit_query.select_related("sending_client", "sender"):
email = m.sender.email
user_counts.setdefault(email, {})
user_counts[email].setdefault(m.sending_client.name, 0)
user_counts[email][m.sending_client.name] += 1
total_counts = {} # type: Dict[str, int]
total_user_counts = {} # type: Dict[str, int]
total_counts = {} # type: Dict[str, int]
total_user_counts = {} # type: Dict[str, int]
for email, counts in user_counts.items():
total_user_counts.setdefault(email, 0)
for client_name, count in counts.items():
@@ -47,7 +47,7 @@ def compute_stats(log_level):
total_user_counts[email] += count
logging.debug("%40s | %10s | %s" % ("User", "Messages", "Percentage Zulip"))
top_percents = {} # type: Dict[int, float]
top_percents = {} # type: Dict[int, float]
for size in [10, 25, 50, 100, 200, len(total_user_counts.keys())]:
top_percents[size] = 0.0
for i, email in enumerate(sorted(total_user_counts.keys(),

View File

@@ -6,6 +6,7 @@ from typing import Any
from argparse import ArgumentParser
from django.core.management.base import BaseCommand
from django.db.models import Count, QuerySet
from django.utils.timezone import now as timezone_now
from zerver.models import UserActivity, UserProfile, Realm, \
get_realm, get_user_profile_by_email
@@ -38,7 +39,7 @@ Usage examples:
#
# Importantly, this does NOT tell you anything about the relative
# volumes of requests from clients.
threshold = datetime.datetime.now() - datetime.timedelta(days=7)
threshold = timezone_now() - datetime.timedelta(days=7)
client_counts = user_activity_objects.filter(
last_visit__gt=threshold).values("client__name").annotate(
count=Count('client__name'))

View File

@@ -3,20 +3,21 @@ from __future__ import absolute_import, print_function
from argparse import ArgumentParser
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.utils.timezone import now as timezone_now
from analytics.models import BaseCount, InstallationCount, RealmCount, \
UserCount, StreamCount
from analytics.lib.counts import COUNT_STATS, CountStat, do_drop_all_analytics_tables
from analytics.lib.fixtures import generate_time_series_data
from analytics.lib.time_utils import time_range
from analytics.models import BaseCount, InstallationCount, RealmCount, \
UserCount, StreamCount, FillState
from zerver.lib.timestamp import floor_to_day
from zerver.models import Realm, UserProfile, Stream, Message, Client
from zerver.models import Realm, UserProfile, Stream, Message, Client, \
RealmAuditLog
from datetime import datetime, timedelta
from six.moves import zip
from typing import Any, List, Optional, Text, Type, Union
from typing import Any, Dict, List, Optional, Text, Type, Union, Mapping
class Command(BaseCommand):
help = """Populates analytics tables with randomly generated data."""
@@ -26,38 +27,40 @@ class Command(BaseCommand):
def create_user(self, email, full_name, is_staff, date_joined, realm):
# type: (Text, Text, Text, bool, datetime, Realm) -> UserProfile
return UserProfile.objects.create(
user = UserProfile.objects.create(
email=email, full_name=full_name, is_staff=is_staff,
realm=realm, short_name=full_name, pointer=-1, last_pointer_updater='none',
api_key='42', date_joined=date_joined)
RealmAuditLog.objects.create(
realm=realm, modified_user=user, event_type='user_created',
event_time=user.date_joined)
return user
def generate_fixture_data(self, stat, business_hours_base, non_business_hours_base,
growth, autocorrelation, spikiness, holiday_rate=0):
# type: (CountStat, float, float, float, float, float, float) -> List[int]
growth, autocorrelation, spikiness, holiday_rate=0,
partial_sum=False):
# type: (CountStat, float, float, float, float, float, float, bool) -> List[int]
self.random_seed += 1
return generate_time_series_data(
days=self.DAYS_OF_DATA, business_hours_base=business_hours_base,
non_business_hours_base=non_business_hours_base, growth=growth,
autocorrelation=autocorrelation, spikiness=spikiness, holiday_rate=holiday_rate,
frequency=stat.frequency, is_gauge=(stat.interval == CountStat.GAUGE),
random_seed=self.random_seed)
frequency=stat.frequency, partial_sum=partial_sum, random_seed=self.random_seed)
def handle(self, *args, **options):
# type: (*Any, **Any) -> None
do_drop_all_analytics_tables()
# I believe this also deletes any objects with this realm as a foreign key
Realm.objects.filter(string_id='analytics').delete()
Client.objects.filter(name__endswith='_').delete()
installation_time = timezone.now() - timedelta(days=self.DAYS_OF_DATA)
last_end_time = floor_to_day(timezone.now())
installation_time = timezone_now() - timedelta(days=self.DAYS_OF_DATA)
last_end_time = floor_to_day(timezone_now())
realm = Realm.objects.create(
string_id='analytics', name='Analytics', domain='analytics.ds',
date_created=installation_time)
string_id='analytics', name='Analytics', date_created=installation_time)
shylock = self.create_user('shylock@analytics.ds', 'Shylock', True, installation_time, realm)
def insert_fixture_data(stat, fixture_data, table):
# type: (CountStat, Dict[Optional[str], List[int]], Type[BaseCount]) -> None
# type: (CountStat, Mapping[Optional[str], List[int]], Type[BaseCount]) -> None
end_times = time_range(last_end_time, last_end_time, stat.frequency,
len(list(fixture_data.values())[0]))
if table == RealmCount:
@@ -70,54 +73,66 @@ class Command(BaseCommand):
value=value, **id_args)
for end_time, value in zip(end_times, values) if value != 0])
stat = COUNT_STATS['active_users:is_bot:day']
stat = COUNT_STATS['realm_active_humans::day']
realm_data = {
'false': self.generate_fixture_data(stat, .1, .03, 3, .5, 3),
'true': self.generate_fixture_data(stat, .01, 0, 1, 0, 1)
} # type: Dict[Optional[str], List[int]]
None: self.generate_fixture_data(stat, .1, .03, 3, .5, 3, partial_sum=True),
} # type: Mapping[Optional[str], List[int]]
insert_fixture_data(stat, realm_data, RealmCount)
FillState.objects.create(property=stat.property, end_time=last_end_time,
state=FillState.DONE)
stat = COUNT_STATS['messages_sent:is_bot:hour']
user_data = {'false': self.generate_fixture_data(stat, 2, 1, 1.5, .6, 8, holiday_rate=.1)}
user_data = {'false': self.generate_fixture_data(
stat, 2, 1, 1.5, .6, 8, holiday_rate=.1)} # type: Mapping[Optional[str], List[int]]
insert_fixture_data(stat, user_data, UserCount)
realm_data = {'false': self.generate_fixture_data(stat, 35, 15, 6, .6, 4),
'true': self.generate_fixture_data(stat, 15, 15, 3, .4, 2)}
insert_fixture_data(stat, realm_data, RealmCount)
FillState.objects.create(property=stat.property, end_time=last_end_time,
state=FillState.DONE)
stat = COUNT_STATS['messages_sent:message_type:day']
user_data = {
'public_stream': self.generate_fixture_data(stat, 1.5, 1, 3, .6, 8),
'private_message': self.generate_fixture_data(stat, .5, .3, 1, .6, 8)}
'private_message': self.generate_fixture_data(stat, .5, .3, 1, .6, 8),
'huddle_message': self.generate_fixture_data(stat, .2, .2, 2, .6, 8)}
insert_fixture_data(stat, user_data, UserCount)
realm_data = {
'public_stream': self.generate_fixture_data(stat, 30, 8, 5, .6, 4),
'private_stream': self.generate_fixture_data(stat, 7, 7, 5, .6, 4),
'private_message': self.generate_fixture_data(stat, 13, 5, 5, .6, 4)}
'private_message': self.generate_fixture_data(stat, 13, 5, 5, .6, 4),
'huddle_message': self.generate_fixture_data(stat, 6, 3, 3, .6, 4)}
insert_fixture_data(stat, realm_data, RealmCount)
FillState.objects.create(property=stat.property, end_time=last_end_time,
state=FillState.DONE)
website_ = Client.objects.create(name='website_')
API_ = Client.objects.create(name='API_')
android_ = Client.objects.create(name='android_')
iOS_ = Client.objects.create(name='iOS_')
react_native_ = Client.objects.create(name='react_native_')
electron_ = Client.objects.create(name='electron_')
barnowl_ = Client.objects.create(name='barnowl_')
plan9_ = Client.objects.create(name='plan9_')
website, created = Client.objects.get_or_create(name='website')
old_desktop, created = Client.objects.get_or_create(name='desktop app Linux 0.3.7')
android, created = Client.objects.get_or_create(name='ZulipAndroid')
iOS, created = Client.objects.get_or_create(name='ZulipiOS')
react_native, created = Client.objects.get_or_create(name='ZulipMobile')
API, created = Client.objects.get_or_create(name='API: Python')
zephyr_mirror, created = Client.objects.get_or_create(name='zephyr_mirror')
unused, created = Client.objects.get_or_create(name='unused')
long_webhook, created = Client.objects.get_or_create(name='ZulipLooooooooooongNameWebhook')
stat = COUNT_STATS['messages_sent:client:day']
user_data = {
website_.id: self.generate_fixture_data(stat, 2, 1, 1.5, .6, 8),
barnowl_.id: self.generate_fixture_data(stat, 0, .3, 1.5, .6, 8)}
website.id: self.generate_fixture_data(stat, 2, 1, 1.5, .6, 8),
zephyr_mirror.id: self.generate_fixture_data(stat, 0, .3, 1.5, .6, 8)}
insert_fixture_data(stat, user_data, UserCount)
realm_data = {
website_.id: self.generate_fixture_data(stat, 30, 20, 5, .6, 3),
API_.id: self.generate_fixture_data(stat, 5, 5, 5, .6, 3),
android_.id: self.generate_fixture_data(stat, 5, 5, 2, .6, 3),
iOS_.id: self.generate_fixture_data(stat, 5, 5, 2, .6, 3),
react_native_.id: self.generate_fixture_data(stat, 5, 5, 10, .6, 3),
electron_.id: self.generate_fixture_data(stat, 5, 3, 8, .6, 3),
barnowl_.id: self.generate_fixture_data(stat, 1, 1, 3, .6, 3),
plan9_.id: self.generate_fixture_data(stat, 0, 0, 0, 0, 0, 0)}
website.id: self.generate_fixture_data(stat, 30, 20, 5, .6, 3),
old_desktop.id: self.generate_fixture_data(stat, 5, 3, 8, .6, 3),
android.id: self.generate_fixture_data(stat, 5, 5, 2, .6, 3),
iOS.id: self.generate_fixture_data(stat, 5, 5, 2, .6, 3),
react_native.id: self.generate_fixture_data(stat, 5, 5, 10, .6, 3),
API.id: self.generate_fixture_data(stat, 5, 5, 5, .6, 3),
zephyr_mirror.id: self.generate_fixture_data(stat, 1, 1, 3, .6, 3),
unused.id: self.generate_fixture_data(stat, 0, 0, 0, 0, 0),
long_webhook.id: self.generate_fixture_data(stat, 5, 5, 2, .6, 3)}
insert_fixture_data(stat, realm_data, RealmCount)
FillState.objects.create(property=stat.property, end_time=last_end_time,
state=FillState.DONE)
# TODO: messages_sent_to_stream:is_bot

View File

@@ -2,7 +2,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from typing import Any
from typing import Any, List
from argparse import ArgumentParser
import datetime
@@ -10,6 +10,8 @@ import pytz
from django.core.management.base import BaseCommand
from django.db.models import Count
from django.utils.timezone import now as timezone_now
from zerver.models import UserProfile, Realm, Stream, Message, Recipient, UserActivity, \
Subscription, UserMessage, get_realm
@@ -29,7 +31,7 @@ class Command(BaseCommand):
def active_users(self, realm):
# type: (Realm) -> List[UserProfile]
# Has been active (on the website, for now) in the last 7 days.
activity_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=7)
activity_cutoff = timezone_now() - datetime.timedelta(days=7)
return [activity.user_profile for activity in (
UserActivity.objects.filter(user_profile__realm=realm,
user_profile__is_active=True,
@@ -39,17 +41,17 @@ class Command(BaseCommand):
def messages_sent_by(self, user, days_ago):
# type: (UserProfile, int) -> int
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
sent_time_cutoff = timezone_now() - datetime.timedelta(days=days_ago)
return human_messages.filter(sender=user, pub_date__gt=sent_time_cutoff).count()
def total_messages(self, realm, days_ago):
# type: (Realm, int) -> int
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
sent_time_cutoff = timezone_now() - datetime.timedelta(days=days_ago)
return Message.objects.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).count()
def human_messages(self, realm, days_ago):
# type: (Realm, int) -> int
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
sent_time_cutoff = timezone_now() - datetime.timedelta(days=days_ago)
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).count()
def api_messages(self, realm, days_ago):
@@ -58,19 +60,19 @@ class Command(BaseCommand):
def stream_messages(self, realm, days_ago):
# type: (Realm, int) -> int
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
sent_time_cutoff = timezone_now() - datetime.timedelta(days=days_ago)
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff,
recipient__type=Recipient.STREAM).count()
def private_messages(self, realm, days_ago):
# type: (Realm, int) -> int
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
sent_time_cutoff = timezone_now() - datetime.timedelta(days=days_ago)
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.HUDDLE).count()
def group_private_messages(self, realm, days_ago):
# type: (Realm, int) -> int
sent_time_cutoff = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=days_ago)
sent_time_cutoff = timezone_now() - datetime.timedelta(days=days_ago)
return human_messages.filter(sender__realm=realm, pub_date__gt=sent_time_cutoff).exclude(
recipient__type=Recipient.STREAM).exclude(recipient__type=Recipient.PERSONAL).count()

View File

@@ -7,18 +7,20 @@ from scripts.lib.zulip_tools import ENDC, WARNING
from argparse import ArgumentParser
from datetime import timedelta
import time
from django.core.management.base import BaseCommand
from django.utils import timezone
from django.utils.timezone import now as timezone_now
from django.utils.timezone import utc as timezone_utc
from django.utils.dateparse import parse_datetime
from django.conf import settings
from analytics.models import RealmCount, UserCount
from analytics.lib.counts import COUNT_STATS, logger, process_count_stat
from zerver.lib.timestamp import datetime_to_string, is_timezone_aware
from zerver.lib.timestamp import floor_to_hour
from zerver.models import UserProfile, Message
from typing import Any
from typing import Any, Dict
class Command(BaseCommand):
help = """Fills Analytics tables.
@@ -30,17 +32,18 @@ class Command(BaseCommand):
parser.add_argument('--time', '-t',
type=str,
help='Update stat tables from current state to --time. Defaults to the current time.',
default=datetime_to_string(timezone.now()))
default=timezone_now().isoformat())
parser.add_argument('--utc',
type=bool,
action='store_true',
help="Interpret --time in UTC.",
default=False)
parser.add_argument('--stat', '-s',
type=str,
help="CountStat to process. If omitted, all stats are processed.")
parser.add_argument('--quiet', '-q',
type=str,
help="Suppress output to stdout.")
parser.add_argument('--verbose',
action='store_true',
help="Print timing information to stdout.",
default=False)
def handle(self, *args, **options):
# type: (*Any, **Any) -> None
@@ -58,18 +61,31 @@ class Command(BaseCommand):
def run_update_analytics_counts(self, options):
# type: (Dict[str, Any]) -> None
fill_to_time = parse_datetime(options['time'])
if options['utc']:
fill_to_time = fill_to_time.replace(tzinfo=timezone.utc)
if not (is_timezone_aware(fill_to_time)):
if options['utc']:
fill_to_time = fill_to_time.replace(tzinfo=timezone_utc)
if fill_to_time.tzinfo is None:
raise ValueError("--time must be timezone aware. Maybe you meant to use the --utc option?")
logger.info("Starting updating analytics counts through %s" % (fill_to_time,))
fill_to_time = floor_to_hour(fill_to_time.astimezone(timezone_utc))
if options['stat'] is not None:
process_count_stat(COUNT_STATS[options['stat']], fill_to_time)
stats = [COUNT_STATS[options['stat']]]
else:
for stat in COUNT_STATS.values():
process_count_stat(stat, fill_to_time)
stats = list(COUNT_STATS.values())
logger.info("Starting updating analytics counts through %s" % (fill_to_time,))
if options['verbose']:
start = time.time()
last = start
for stat in stats:
process_count_stat(stat, fill_to_time)
if options['verbose']:
print("Updated %s in %.3fs" % (stat.property, time.time() - last))
last = time.time()
if options['verbose']:
print("Finished updating analytics counts through %s in %.3fs" %
(fill_to_time, time.time() - start))
logger.info("Finished updating analytics counts through %s" % (fill_to_time,))

View File

@@ -7,6 +7,8 @@ import pytz
from typing import Any
from django.core.management.base import BaseCommand
from django.utils.timezone import now as timezone_now
from zerver.models import UserProfile, Realm, Stream, Message, get_realm
from six.moves import range
@@ -20,8 +22,8 @@ class Command(BaseCommand):
def messages_sent_by(self, user, week):
# type: (UserProfile, int) -> int
start = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=(week + 1)*7)
end = datetime.datetime.now(tz=pytz.utc) - datetime.timedelta(days=week*7)
start = timezone_now() - datetime.timedelta(days=(week + 1)*7)
end = timezone_now() - datetime.timedelta(days=week*7)
return Message.objects.filter(sender=user, pub_date__gt=start, pub_date__lte=end).count()
def handle(self, *args, **options):

View File

@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
from django.db.migrations.state import StateApps
from django.db import migrations
def delete_messages_sent_to_stream_stat(apps, schema_editor):
# type: (StateApps, DatabaseSchemaEditor) -> None
UserCount = apps.get_model('analytics', 'UserCount')
StreamCount = apps.get_model('analytics', 'StreamCount')
RealmCount = apps.get_model('analytics', 'RealmCount')
InstallationCount = apps.get_model('analytics', 'InstallationCount')
FillState = apps.get_model('analytics', 'FillState')
property = 'messages_sent_to_stream:is_bot'
UserCount.objects.filter(property=property).delete()
StreamCount.objects.filter(property=property).delete()
RealmCount.objects.filter(property=property).delete()
InstallationCount.objects.filter(property=property).delete()
FillState.objects.filter(property=property).delete()
class Migration(migrations.Migration):
dependencies = [
('analytics', '0008_add_count_indexes'),
]
operations = [
migrations.RunPython(delete_messages_sent_to_stream_stat),
]

View File

@@ -0,0 +1,27 @@
# -*- coding: utf-8 -*-
from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
from django.db.migrations.state import StateApps
from django.db import migrations
def clear_message_sent_by_message_type_values(apps, schema_editor):
# type: (StateApps, DatabaseSchemaEditor) -> None
UserCount = apps.get_model('analytics', 'UserCount')
StreamCount = apps.get_model('analytics', 'StreamCount')
RealmCount = apps.get_model('analytics', 'RealmCount')
InstallationCount = apps.get_model('analytics', 'InstallationCount')
FillState = apps.get_model('analytics', 'FillState')
property = 'messages_sent:message_type:day'
UserCount.objects.filter(property=property).delete()
StreamCount.objects.filter(property=property).delete()
RealmCount.objects.filter(property=property).delete()
InstallationCount.objects.filter(property=property).delete()
FillState.objects.filter(property=property).delete()
class Migration(migrations.Migration):
dependencies = [('analytics', '0009_remove_messages_to_stream_stat')]
operations = [
migrations.RunPython(clear_message_sent_by_message_type_values),
]

View File

@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from django.db.backends.postgresql_psycopg2.schema import DatabaseSchemaEditor
from django.db.migrations.state import StateApps
from django.db import migrations
def clear_analytics_tables(apps, schema_editor):
# type: (StateApps, DatabaseSchemaEditor) -> None
UserCount = apps.get_model('analytics', 'UserCount')
StreamCount = apps.get_model('analytics', 'StreamCount')
RealmCount = apps.get_model('analytics', 'RealmCount')
InstallationCount = apps.get_model('analytics', 'InstallationCount')
FillState = apps.get_model('analytics', 'FillState')
UserCount.objects.all().delete()
StreamCount.objects.all().delete()
RealmCount.objects.all().delete()
InstallationCount.objects.all().delete()
FillState.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [
('analytics', '0010_clear_messages_sent_values'),
]
operations = [
migrations.RunPython(clear_analytics_tables),
]

View File

@@ -1,24 +1,23 @@
from django.db import models
from django.utils import timezone
from zerver.models import Realm, UserProfile, Stream, Recipient
from zerver.lib.str_utils import ModelReprMixin
from zerver.lib.timestamp import datetime_to_UTC, floor_to_day
from zerver.lib.timestamp import floor_to_day
import datetime
from typing import Optional, Tuple, Union, Dict, Any, Text
class FillState(ModelReprMixin, models.Model):
property = models.CharField(max_length=40, unique=True) # type: Text
end_time = models.DateTimeField() # type: datetime.datetime
property = models.CharField(max_length=40, unique=True) # type: Text
end_time = models.DateTimeField() # type: datetime.datetime
# Valid states are {DONE, STARTED}
DONE = 1
STARTED = 2
state = models.PositiveSmallIntegerField() # type: int
state = models.PositiveSmallIntegerField() # type: int
last_modified = models.DateTimeField(auto_now=True) # type: datetime.datetime
last_modified = models.DateTimeField(auto_now=True) # type: datetime.datetime
def __unicode__(self):
# type: () -> Text
@@ -29,11 +28,20 @@ class FillState(ModelReprMixin, models.Model):
def installation_epoch():
# type: () -> datetime.datetime
earliest_realm_creation = Realm.objects.aggregate(models.Min('date_created'))['date_created__min']
return floor_to_day(datetime_to_UTC(earliest_realm_creation))
return floor_to_day(earliest_realm_creation)
def last_successful_fill(property):
# type: (str) -> Optional[datetime.datetime]
fillstate = FillState.objects.filter(property=property).first()
if fillstate is None:
return None
if fillstate.state == FillState.DONE:
return fillstate.end_time
return fillstate.end_time - datetime.timedelta(hours=1)
# would only ever make entries here by hand
class Anomaly(ModelReprMixin, models.Model):
info = models.CharField(max_length=1000) # type: Text
info = models.CharField(max_length=1000) # type: Text
def __unicode__(self):
# type: () -> Text
@@ -43,40 +51,20 @@ class BaseCount(ModelReprMixin, models.Model):
# Note: When inheriting from BaseCount, you may want to rearrange
# the order of the columns in the migration to make sure they
# match how you'd like the table to be arranged.
property = models.CharField(max_length=32) # type: Text
subgroup = models.CharField(max_length=16, null=True) # type: Text
end_time = models.DateTimeField() # type: datetime.datetime
value = models.BigIntegerField() # type: int
anomaly = models.ForeignKey(Anomaly, null=True) # type: Optional[Anomaly]
property = models.CharField(max_length=32) # type: Text
subgroup = models.CharField(max_length=16, null=True) # type: Optional[Text]
end_time = models.DateTimeField() # type: datetime.datetime
value = models.BigIntegerField() # type: int
anomaly = models.ForeignKey(Anomaly, null=True) # type: Optional[Anomaly]
class Meta(object):
abstract = True
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
raise NotImplementedError
@staticmethod
def key_model():
# type: () -> models.Model
raise NotImplementedError
class InstallationCount(BaseCount):
class Meta(object):
unique_together = ("property", "subgroup", "end_time")
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ()
@staticmethod
def key_model():
# type: () -> models.Model
return None
def __unicode__(self):
# type: () -> Text
return u"<InstallationCount: %s %s %s>" % (self.property, self.subgroup, self.value)
@@ -88,16 +76,6 @@ class RealmCount(BaseCount):
unique_together = ("realm", "property", "subgroup", "end_time")
index_together = ["property", "end_time"]
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ('realm_id',)
@staticmethod
def key_model():
# type: () -> models.Model
return Realm
def __unicode__(self):
# type: () -> Text
return u"<RealmCount: %s %s %s %s>" % (self.realm, self.property, self.subgroup, self.value)
@@ -112,16 +90,6 @@ class UserCount(BaseCount):
# aggregating from users to realms
index_together = ["property", "realm", "end_time"]
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ('user_id', 'realm_id')
@staticmethod
def key_model():
# type: () -> models.Model
return UserProfile
def __unicode__(self):
# type: () -> Text
return u"<UserCount: %s %s %s %s>" % (self.user, self.property, self.subgroup, self.value)
@@ -136,16 +104,6 @@ class StreamCount(BaseCount):
# aggregating from streams to realms
index_together = ["property", "realm", "end_time"]
@staticmethod
def extended_id():
# type: () -> Tuple[str, ...]
return ('stream_id', 'realm_id')
@staticmethod
def key_model():
# type: () -> models.Model
return Stream
def __unicode__(self):
# type: () -> Text
return u"<StreamCount: %s %s %s %s %s>" % (self.stream, self.property, self.subgroup, self.value, self.id)

View File

@@ -1,39 +1,47 @@
from __future__ import absolute_import
from django.apps import apps
from django.db import models
from django.db.models import Sum
from django.test import TestCase
from django.utils import timezone
from django.utils.timezone import now as timezone_now
from django.utils.timezone import utc as timezone_utc
from analytics.lib.counts import CountStat, COUNT_STATS, process_count_stat, \
zerver_count_user_by_realm, zerver_count_message_by_user, \
zerver_count_message_by_stream, zerver_count_stream_by_realm, \
do_fill_count_stat_at_hour, ZerverCountQuery
do_fill_count_stat_at_hour, do_increment_logging_stat, DataCollector, \
sql_data_collector, LoggingCountStat, do_aggregate_to_summary_table, \
do_drop_all_analytics_tables, DependentCountStat
from analytics.models import BaseCount, InstallationCount, RealmCount, \
UserCount, StreamCount, FillState, installation_epoch
UserCount, StreamCount, FillState, Anomaly, installation_epoch, \
last_successful_fill
from zerver.lib.actions import do_create_user, do_deactivate_user, \
do_activate_user, do_reactivate_user, update_user_activity_interval
from zerver.lib.timestamp import floor_to_day
from zerver.models import Realm, UserProfile, Message, Stream, Recipient, \
Huddle, Client, get_user_profile_by_email, get_client
Huddle, Client, UserActivityInterval, RealmAuditLog, \
get_user_profile_by_email, get_client
from datetime import datetime, timedelta
import ujson
from six.moves import range
from typing import Any, Type, Optional, Text, Tuple, List, Union
from typing import Any, Dict, List, Optional, Text, Tuple, Type, Union
class AnalyticsTestCase(TestCase):
MINUTE = timedelta(seconds = 60)
HOUR = MINUTE * 60
DAY = HOUR * 24
TIME_ZERO = datetime(1988, 3, 14).replace(tzinfo=timezone.utc)
TIME_ZERO = datetime(1988, 3, 14).replace(tzinfo=timezone_utc)
TIME_LAST_HOUR = TIME_ZERO - HOUR
def setUp(self):
# type: () -> None
self.default_realm = Realm.objects.create(
string_id='realmtest', name='Realm Test',
domain='test.analytics', date_created=self.TIME_ZERO - 2*self.DAY)
string_id='realmtest', name='Realm Test', date_created=self.TIME_ZERO - 2*self.DAY)
# used to generate unique names in self.create_*
self.name_counter = 100
# used as defaults in self.assertCountEquals
self.current_property = None # type: Optional[str]
self.current_property = None # type: Optional[str]
# Lightweight creation of users, streams, and messages
def create_user(self, **kwargs):
@@ -103,7 +111,7 @@ class AnalyticsTestCase(TestCase):
self.assertEqual(queryset.values_list('value', flat=True)[0], value)
def assertTableState(self, table, arg_keys, arg_values):
# type: (Type[BaseCount], List[str], List[List[Union[int, str, Realm, UserProfile, Stream]]]) -> None
# type: (Type[BaseCount], List[str], List[List[Union[int, str, bool, datetime, Realm, UserProfile, Stream]]]) -> None
"""Assert that the state of a *Count table is what it should be.
Example usage:
@@ -128,9 +136,10 @@ class AnalyticsTestCase(TestCase):
defaults = {
'property': self.current_property,
'subgroup': None,
'end_time': self.TIME_ZERO}
'end_time': self.TIME_ZERO,
'value': 1}
for values in arg_values:
kwargs = {} # type: Dict[str, Any]
kwargs = {} # type: Dict[str, Any]
for i in range(len(values)):
kwargs[arg_keys[i]] = values[i]
for key, value in defaults.items():
@@ -147,20 +156,15 @@ class AnalyticsTestCase(TestCase):
self.assertEqual(table.objects.count(), len(arg_values))
class TestProcessCountStat(AnalyticsTestCase):
def make_dummy_count_stat(self, current_time):
# type: (datetime) -> CountStat
dummy_query = """INSERT INTO analytics_realmcount (realm_id, property, end_time, value)
VALUES (1, 'test stat', '%(end_time)s', 22)""" % {'end_time': current_time}
count_stat = CountStat('test stat', ZerverCountQuery(Recipient, UserCount, dummy_query),
{}, None, CountStat.HOUR, False)
return count_stat
def make_dummy_count_stat(self, property):
# type: (str) -> CountStat
query = """INSERT INTO analytics_realmcount (realm_id, value, property, end_time)
VALUES (%s, 1, '%s', %%%%(time_end)s)""" % (self.default_realm.id, property)
return CountStat(property, sql_data_collector(RealmCount, query, None), CountStat.HOUR)
def assertFillStateEquals(self, end_time, state = FillState.DONE, property = None):
# type: (datetime, int, Optional[Text]) -> None
count_stat = self.make_dummy_count_stat(end_time)
if property is None:
property = count_stat.property
fill_state = FillState.objects.filter(property=property).first()
def assertFillStateEquals(self, stat, end_time, state=FillState.DONE):
# type: (CountStat, datetime, int) -> None
fill_state = FillState.objects.filter(property=stat.property).first()
self.assertEqual(fill_state.end_time, end_time)
self.assertEqual(fill_state.state, state)
@@ -168,29 +172,131 @@ class TestProcessCountStat(AnalyticsTestCase):
# type: () -> None
# process new stat
current_time = installation_epoch() + self.HOUR
count_stat = self.make_dummy_count_stat(current_time)
property = count_stat.property
process_count_stat(count_stat, current_time)
self.assertFillStateEquals(current_time)
self.assertEqual(InstallationCount.objects.filter(property=property).count(), 1)
stat = self.make_dummy_count_stat('test stat')
process_count_stat(stat, current_time)
self.assertFillStateEquals(stat, current_time)
self.assertEqual(InstallationCount.objects.filter(property=stat.property).count(), 1)
# dirty stat
FillState.objects.filter(property=property).update(state=FillState.STARTED)
process_count_stat(count_stat, current_time)
self.assertFillStateEquals(current_time)
self.assertEqual(InstallationCount.objects.filter(property=property).count(), 1)
FillState.objects.filter(property=stat.property).update(state=FillState.STARTED)
process_count_stat(stat, current_time)
self.assertFillStateEquals(stat, current_time)
self.assertEqual(InstallationCount.objects.filter(property=stat.property).count(), 1)
# clean stat, no update
process_count_stat(count_stat, current_time)
self.assertFillStateEquals(current_time)
self.assertEqual(InstallationCount.objects.filter(property=property).count(), 1)
process_count_stat(stat, current_time)
self.assertFillStateEquals(stat, current_time)
self.assertEqual(InstallationCount.objects.filter(property=stat.property).count(), 1)
# clean stat, with update
current_time = current_time + self.HOUR
count_stat = self.make_dummy_count_stat(current_time)
process_count_stat(count_stat, current_time)
self.assertFillStateEquals(current_time)
self.assertEqual(InstallationCount.objects.filter(property=property).count(), 2)
stat = self.make_dummy_count_stat('test stat')
process_count_stat(stat, current_time)
self.assertFillStateEquals(stat, current_time)
self.assertEqual(InstallationCount.objects.filter(property=stat.property).count(), 2)
def test_bad_fill_to_time(self):
# type: () -> None
stat = self.make_dummy_count_stat('test stat')
with self.assertRaises(ValueError):
process_count_stat(stat, installation_epoch() + 65*self.MINUTE)
with self.assertRaises(ValueError):
process_count_stat(stat, installation_epoch().replace(tzinfo=None) + self.HOUR) # type: ignore # https://github.com/python/typeshed/pull/1347
# This tests the LoggingCountStat branch of the code in do_delete_counts_at_hour.
# It is important that do_delete_counts_at_hour not delete any of the collected
# logging data!
def test_process_logging_stat(self):
# type: () -> None
end_time = self.TIME_ZERO
user_stat = LoggingCountStat('user stat', UserCount, CountStat.DAY)
stream_stat = LoggingCountStat('stream stat', StreamCount, CountStat.DAY)
realm_stat = LoggingCountStat('realm stat', RealmCount, CountStat.DAY)
user = self.create_user()
stream = self.create_stream_with_recipient()[0]
realm = self.default_realm
UserCount.objects.create(
user=user, realm=realm, property=user_stat.property, end_time=end_time, value=5)
StreamCount.objects.create(
stream=stream, realm=realm, property=stream_stat.property, end_time=end_time, value=5)
RealmCount.objects.create(
realm=realm, property=realm_stat.property, end_time=end_time, value=5)
# Normal run of process_count_stat
for stat in [user_stat, stream_stat, realm_stat]:
process_count_stat(stat, end_time)
self.assertTableState(UserCount, ['property', 'value'], [[user_stat.property, 5]])
self.assertTableState(StreamCount, ['property', 'value'], [[stream_stat.property, 5]])
self.assertTableState(RealmCount, ['property', 'value'],
[[user_stat.property, 5], [stream_stat.property, 5], [realm_stat.property, 5]])
self.assertTableState(InstallationCount, ['property', 'value'],
[[user_stat.property, 5], [stream_stat.property, 5], [realm_stat.property, 5]])
# Change the logged data and mark FillState as dirty
UserCount.objects.update(value=6)
StreamCount.objects.update(value=6)
RealmCount.objects.filter(property=realm_stat.property).update(value=6)
FillState.objects.update(state=FillState.STARTED)
# Check that the change propagated (and the collected data wasn't deleted)
for stat in [user_stat, stream_stat, realm_stat]:
process_count_stat(stat, end_time)
self.assertTableState(UserCount, ['property', 'value'], [[user_stat.property, 6]])
self.assertTableState(StreamCount, ['property', 'value'], [[stream_stat.property, 6]])
self.assertTableState(RealmCount, ['property', 'value'],
[[user_stat.property, 6], [stream_stat.property, 6], [realm_stat.property, 6]])
self.assertTableState(InstallationCount, ['property', 'value'],
[[user_stat.property, 6], [stream_stat.property, 6], [realm_stat.property, 6]])
def test_process_dependent_stat(self):
# type: () -> None
stat1 = self.make_dummy_count_stat('stat1')
stat2 = self.make_dummy_count_stat('stat2')
query = """INSERT INTO analytics_realmcount (realm_id, value, property, end_time)
VALUES (%s, 1, '%s', %%%%(time_end)s)""" % (self.default_realm.id, 'stat3')
stat3 = DependentCountStat('stat3', sql_data_collector(RealmCount, query, None), CountStat.HOUR,
dependencies=['stat1', 'stat2'])
hour = [installation_epoch() + i*self.HOUR for i in range(5)]
# test when one dependency has been run, and the other hasn't
process_count_stat(stat1, hour[2])
process_count_stat(stat3, hour[1])
self.assertTableState(InstallationCount, ['property', 'end_time'],
[['stat1', hour[1]], ['stat1', hour[2]]])
self.assertFillStateEquals(stat3, hour[0])
# test that we don't fill past the fill_to_time argument, even if
# dependencies have later last_successful_fill
process_count_stat(stat2, hour[3])
process_count_stat(stat3, hour[1])
self.assertTableState(InstallationCount, ['property', 'end_time'],
[['stat1', hour[1]], ['stat1', hour[2]],
['stat2', hour[1]], ['stat2', hour[2]], ['stat2', hour[3]],
['stat3', hour[1]]])
self.assertFillStateEquals(stat3, hour[1])
# test that we don't fill past the dependency last_successful_fill times,
# even if fill_to_time is later
process_count_stat(stat3, hour[4])
self.assertTableState(InstallationCount, ['property', 'end_time'],
[['stat1', hour[1]], ['stat1', hour[2]],
['stat2', hour[1]], ['stat2', hour[2]], ['stat2', hour[3]],
['stat3', hour[1]], ['stat3', hour[2]]])
self.assertFillStateEquals(stat3, hour[2])
# test daily dependent stat with hourly dependencies
query = """INSERT INTO analytics_realmcount (realm_id, value, property, end_time)
VALUES (%s, 1, '%s', %%%%(time_end)s)""" % (self.default_realm.id, 'stat4')
stat4 = DependentCountStat('stat4', sql_data_collector(RealmCount, query, None), CountStat.DAY,
dependencies=['stat1', 'stat2'])
hour24 = installation_epoch() + 24*self.HOUR
hour25 = installation_epoch() + 25*self.HOUR
process_count_stat(stat1, hour25)
process_count_stat(stat2, hour25)
process_count_stat(stat4, hour25)
self.assertEqual(InstallationCount.objects.filter(property='stat4').count(), 1)
self.assertFillStateEquals(stat4, hour24)
class TestCountStats(AnalyticsTestCase):
def setUp(self):
@@ -201,7 +307,7 @@ class TestCountStats(AnalyticsTestCase):
# the queries).
self.second_realm = Realm.objects.create(
string_id='second-realm', name='Second Realm',
domain='second.analytics', date_created=self.TIME_ZERO-2*self.DAY)
date_created=self.TIME_ZERO-2*self.DAY)
for minutes_ago in [0, 1, 61, 60*24+1]:
creation_time = self.TIME_ZERO - minutes_ago*self.MINUTE
user = self.create_user(email='user-%s@second.analytics' % (minutes_ago,),
@@ -217,7 +323,7 @@ class TestCountStats(AnalyticsTestCase):
# messages_* CountStats
self.no_message_realm = Realm.objects.create(
string_id='no-message-realm', name='No Message Realm',
domain='no.message', date_created=self.TIME_ZERO-2*self.DAY)
date_created=self.TIME_ZERO-2*self.DAY)
self.create_user(realm=self.no_message_realm)
self.create_stream_with_recipient(realm=self.no_message_realm)
# This huddle should not show up anywhere
@@ -323,16 +429,19 @@ class TestCountStats(AnalyticsTestCase):
[2, 'private_stream', user2],
[2, 'public_stream', user1],
[1, 'public_stream', user2],
[2, 'private_message', user1],
[2, 'private_message', user2],
[1, 'private_message', user1],
[1, 'private_message', user2],
[1, 'private_message', user3],
[1, 'huddle_message', user1],
[1, 'huddle_message', user2],
[1, 'public_stream', self.hourly_user],
[1, 'public_stream', self.daily_user]])
self.assertTableState(RealmCount, ['value', 'subgroup', 'realm'],
[[3, 'private_stream'], [3, 'public_stream'], [5, 'private_message'],
[2, 'public_stream', self.second_realm]])
[[3, 'private_stream'], [3, 'public_stream'], [3, 'private_message'],
[2, 'huddle_message'], [2, 'public_stream', self.second_realm]])
self.assertTableState(InstallationCount, ['value', 'subgroup'],
[[3, 'private_stream'], [5, 'public_stream'], [5, 'private_message']])
[[3, 'private_stream'], [5, 'public_stream'], [3, 'private_message'],
[2, 'huddle_message']])
self.assertTableState(StreamCount, [], [])
def test_messages_sent_to_recipients_with_same_id(self):
@@ -351,7 +460,8 @@ class TestCountStats(AnalyticsTestCase):
do_fill_count_stat_at_hour(stat, self.TIME_ZERO)
self.assertCountEquals(UserCount, 2, subgroup='private_message')
self.assertCountEquals(UserCount, 1, subgroup='private_message')
self.assertCountEquals(UserCount, 1, subgroup='huddle_message')
self.assertCountEquals(UserCount, 1, subgroup='public_stream')
def test_messages_sent_by_client(self):
@@ -377,7 +487,7 @@ class TestCountStats(AnalyticsTestCase):
do_fill_count_stat_at_hour(stat, self.TIME_ZERO)
client2_id = str(client2.id)
website_client_id = str(get_client('website').id) # default for self.create_message
website_client_id = str(get_client('website').id) # default for self.create_message
self.assertTableState(UserCount, ['value', 'subgroup', 'user'],
[[2, website_client_id, user1],
[1, client2_id, user1], [2, client2_id, user2],
@@ -392,7 +502,7 @@ class TestCountStats(AnalyticsTestCase):
def test_messages_sent_to_stream_by_is_bot(self):
# type: () -> None
stat = COUNT_STATS['messages_sent_to_stream:is_bot:hour']
stat = COUNT_STATS['messages_in_stream:is_bot:day']
self.current_property = stat.property
bot = self.create_user(is_bot=True)
@@ -420,9 +530,520 @@ class TestCountStats(AnalyticsTestCase):
self.assertTableState(StreamCount, ['value', 'subgroup', 'stream'],
[[2, 'false', stream1], [1, 'false', stream2], [2, 'true', stream2],
# "hourly" stream, from TestCountStats.setUp
[1, 'false', Stream.objects.get(name='stream 1')]])
# "hourly" and "daily" stream, from TestCountStats.setUp
[1, 'false', Stream.objects.get(name='stream 1')],
[1, 'false', Stream.objects.get(name='stream 61')]])
self.assertTableState(RealmCount, ['value', 'subgroup', 'realm'],
[[3, 'false'], [2, 'true'], [1, 'false', self.second_realm]])
self.assertTableState(InstallationCount, ['value', 'subgroup'], [[4, 'false'], [2, 'true']])
[[3, 'false'], [2, 'true'], [2, 'false', self.second_realm]])
self.assertTableState(InstallationCount, ['value', 'subgroup'], [[5, 'false'], [2, 'true']])
self.assertTableState(UserCount, [], [])
def create_interval(self, user, start_offset, end_offset):
# type: (UserProfile, timedelta, timedelta) -> None
UserActivityInterval.objects.create(
user_profile=user, start=self.TIME_ZERO-start_offset,
end=self.TIME_ZERO-end_offset)
def test_15day_actives(self):
# type: () -> None
stat = COUNT_STATS['15day_actives::day']
self.current_property = stat.property
_15day = 15*self.DAY - UserActivityInterval.MIN_INTERVAL_LENGTH
# Outside time range, should not appear. Also tests upper boundary.
user1 = self.create_user()
self.create_interval(user1, _15day + self.DAY, _15day + timedelta(seconds=1))
self.create_interval(user1, timedelta(0), -self.HOUR)
# On lower boundary, should appear
user2 = self.create_user()
self.create_interval(user2, _15day + self.DAY, _15day)
# Multiple intervals, including one outside boundary
user3 = self.create_user()
self.create_interval(user3, 20*self.DAY, 19*self.DAY)
self.create_interval(user3, 20*self.HOUR, 19*self.HOUR)
self.create_interval(user3, 20*self.MINUTE, 19*self.MINUTE)
# Intervals crossing boundary
user4 = self.create_user()
self.create_interval(user4, 20*self.DAY, 10*self.DAY)
user5 = self.create_user()
self.create_interval(user5, self.MINUTE, -self.MINUTE)
# Interval subsuming time range
user6 = self.create_user()
self.create_interval(user6, 20*self.DAY, -2*self.DAY)
# Second realm
user7 = self.create_user(realm=self.second_realm)
self.create_interval(user7, 20*self.MINUTE, 19*self.MINUTE)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['value', 'user'],
[[1, user2], [1, user3], [1, user4], [1, user5], [1, user6], [1, user7]])
self.assertTableState(RealmCount, ['value', 'realm'],
[[5, self.default_realm], [1, self.second_realm]])
self.assertTableState(InstallationCount, ['value'], [[6]])
self.assertTableState(StreamCount, [], [])
def test_minutes_active(self):
# type: () -> None
stat = COUNT_STATS['minutes_active::day']
self.current_property = stat.property
# Outside time range, should not appear. Also testing for intervals
# starting and ending on boundary
user1 = self.create_user()
self.create_interval(user1, 25*self.HOUR, self.DAY)
self.create_interval(user1, timedelta(0), -self.HOUR)
# Multiple intervals, including one outside boundary
user2 = self.create_user()
self.create_interval(user2, 20*self.DAY, 19*self.DAY)
self.create_interval(user2, 20*self.HOUR, 19*self.HOUR)
self.create_interval(user2, 20*self.MINUTE, 19*self.MINUTE)
# Intervals crossing boundary
user3 = self.create_user()
self.create_interval(user3, 25*self.HOUR, 22*self.HOUR)
self.create_interval(user3, self.MINUTE, -self.MINUTE)
# Interval subsuming time range
user4 = self.create_user()
self.create_interval(user4, 2*self.DAY, -2*self.DAY)
# Less than 60 seconds, should not appear
user5 = self.create_user()
self.create_interval(user5, self.MINUTE, timedelta(seconds=30))
self.create_interval(user5, timedelta(seconds=20), timedelta(seconds=10))
# Second realm
user6 = self.create_user(realm=self.second_realm)
self.create_interval(user6, 20*self.MINUTE, 19*self.MINUTE)
do_fill_count_stat_at_hour(stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['value', 'user'],
[[61, user2], [121, user3], [24*60, user4], [1, user6]])
self.assertTableState(RealmCount, ['value', 'realm'],
[[61 + 121 + 24*60, self.default_realm], [1, self.second_realm]])
self.assertTableState(InstallationCount, ['value'], [[61 + 121 + 24*60 + 1]])
self.assertTableState(StreamCount, [], [])
class TestDoAggregateToSummaryTable(AnalyticsTestCase):
# do_aggregate_to_summary_table is mostly tested by the end to end
# nature of the tests in TestCountStats. But want to highlight one
# feature important for keeping the size of the analytics tables small,
# which is that if there is no relevant data in the table being
# aggregated, the aggregation table doesn't get a row with value 0.
def test_no_aggregated_zeros(self):
# type: () -> None
stat = LoggingCountStat('test stat', UserCount, CountStat.HOUR)
do_aggregate_to_summary_table(stat, self.TIME_ZERO)
self.assertFalse(RealmCount.objects.exists())
self.assertFalse(InstallationCount.objects.exists())
class TestDoIncrementLoggingStat(AnalyticsTestCase):
def test_table_and_id_args(self):
# type: () -> None
# For realms, streams, and users, tests that the new rows are going to
# the appropriate *Count table, and that using a different zerver_object
# results in a new row being created
self.current_property = 'test'
second_realm = Realm.objects.create(string_id='moo', name='moo')
stat = LoggingCountStat('test', RealmCount, CountStat.DAY)
do_increment_logging_stat(self.default_realm, stat, None, self.TIME_ZERO)
do_increment_logging_stat(second_realm, stat, None, self.TIME_ZERO)
self.assertTableState(RealmCount, ['realm'], [[self.default_realm], [second_realm]])
user1 = self.create_user()
user2 = self.create_user()
stat = LoggingCountStat('test', UserCount, CountStat.DAY)
do_increment_logging_stat(user1, stat, None, self.TIME_ZERO)
do_increment_logging_stat(user2, stat, None, self.TIME_ZERO)
self.assertTableState(UserCount, ['user'], [[user1], [user2]])
stream1 = self.create_stream_with_recipient()[0]
stream2 = self.create_stream_with_recipient()[0]
stat = LoggingCountStat('test', StreamCount, CountStat.DAY)
do_increment_logging_stat(stream1, stat, None, self.TIME_ZERO)
do_increment_logging_stat(stream2, stat, None, self.TIME_ZERO)
self.assertTableState(StreamCount, ['stream'], [[stream1], [stream2]])
def test_frequency(self):
# type: () -> None
times = [self.TIME_ZERO - self.MINUTE*i for i in [0, 1, 61, 24*60+1]]
stat = LoggingCountStat('day test', RealmCount, CountStat.DAY)
for time_ in times:
do_increment_logging_stat(self.default_realm, stat, None, time_)
stat = LoggingCountStat('hour test', RealmCount, CountStat.HOUR)
for time_ in times:
do_increment_logging_stat(self.default_realm, stat, None, time_)
self.assertTableState(RealmCount, ['value', 'property', 'end_time'],
[[3, 'day test', self.TIME_ZERO],
[1, 'day test', self.TIME_ZERO - self.DAY],
[2, 'hour test', self.TIME_ZERO],
[1, 'hour test', self.TIME_LAST_HOUR],
[1, 'hour test', self.TIME_ZERO - self.DAY]])
def test_get_or_create(self):
# type: () -> None
stat = LoggingCountStat('test', RealmCount, CountStat.HOUR)
# All these should trigger the create part of get_or_create.
# property is tested in test_frequency, and id_args are tested in test_id_args,
# so this only tests a new subgroup and end_time
do_increment_logging_stat(self.default_realm, stat, 'subgroup1', self.TIME_ZERO)
do_increment_logging_stat(self.default_realm, stat, 'subgroup2', self.TIME_ZERO)
do_increment_logging_stat(self.default_realm, stat, 'subgroup1', self.TIME_LAST_HOUR)
self.current_property = 'test'
self.assertTableState(RealmCount, ['value', 'subgroup', 'end_time'],
[[1, 'subgroup1', self.TIME_ZERO], [1, 'subgroup2', self.TIME_ZERO],
[1, 'subgroup1', self.TIME_LAST_HOUR]])
# This should trigger the get part of get_or_create
do_increment_logging_stat(self.default_realm, stat, 'subgroup1', self.TIME_ZERO)
self.assertTableState(RealmCount, ['value', 'subgroup', 'end_time'],
[[2, 'subgroup1', self.TIME_ZERO], [1, 'subgroup2', self.TIME_ZERO],
[1, 'subgroup1', self.TIME_LAST_HOUR]])
def test_increment(self):
# type: () -> None
stat = LoggingCountStat('test', RealmCount, CountStat.DAY)
self.current_property = 'test'
do_increment_logging_stat(self.default_realm, stat, None, self.TIME_ZERO, increment=-1)
self.assertTableState(RealmCount, ['value'], [[-1]])
do_increment_logging_stat(self.default_realm, stat, None, self.TIME_ZERO, increment=3)
self.assertTableState(RealmCount, ['value'], [[2]])
do_increment_logging_stat(self.default_realm, stat, None, self.TIME_ZERO)
self.assertTableState(RealmCount, ['value'], [[3]])
class TestLoggingCountStats(AnalyticsTestCase):
def test_aggregation(self):
# type: () -> None
stat = LoggingCountStat('realm test', RealmCount, CountStat.DAY)
do_increment_logging_stat(self.default_realm, stat, None, self.TIME_ZERO)
process_count_stat(stat, self.TIME_ZERO)
user = self.create_user()
stat = LoggingCountStat('user test', UserCount, CountStat.DAY)
do_increment_logging_stat(user, stat, None, self.TIME_ZERO)
process_count_stat(stat, self.TIME_ZERO)
stream = self.create_stream_with_recipient()[0]
stat = LoggingCountStat('stream test', StreamCount, CountStat.DAY)
do_increment_logging_stat(stream, stat, None, self.TIME_ZERO)
process_count_stat(stat, self.TIME_ZERO)
self.assertTableState(InstallationCount, ['property', 'value'],
[['realm test', 1], ['user test', 1], ['stream test', 1]])
self.assertTableState(RealmCount, ['property', 'value'],
[['realm test', 1], ['user test', 1], ['stream test', 1]])
self.assertTableState(UserCount, ['property', 'value'], [['user test', 1]])
self.assertTableState(StreamCount, ['property', 'value'], [['stream test', 1]])
def test_active_users_log_by_is_bot(self):
# type: () -> None
property = 'active_users_log:is_bot:day'
user = do_create_user('email', 'password', self.default_realm, 'full_name', 'short_name')
self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
.aggregate(Sum('value'))['value__sum'])
do_deactivate_user(user)
self.assertEqual(0, RealmCount.objects.filter(property=property, subgroup=False)
.aggregate(Sum('value'))['value__sum'])
do_activate_user(user)
self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
.aggregate(Sum('value'))['value__sum'])
do_deactivate_user(user)
self.assertEqual(0, RealmCount.objects.filter(property=property, subgroup=False)
.aggregate(Sum('value'))['value__sum'])
do_reactivate_user(user)
self.assertEqual(1, RealmCount.objects.filter(property=property, subgroup=False)
.aggregate(Sum('value'))['value__sum'])
class TestDeleteStats(AnalyticsTestCase):
def test_do_drop_all_analytics_tables(self):
# type: () -> None
user = self.create_user()
stream = self.create_stream_with_recipient()[0]
count_args = {'property': 'test', 'end_time': self.TIME_ZERO, 'value': 10}
UserCount.objects.create(user=user, realm=user.realm, **count_args)
StreamCount.objects.create(stream=stream, realm=stream.realm, **count_args)
RealmCount.objects.create(realm=user.realm, **count_args)
InstallationCount.objects.create(**count_args)
FillState.objects.create(property='test', end_time=self.TIME_ZERO, state=FillState.DONE)
Anomaly.objects.create(info='test anomaly')
analytics = apps.get_app_config('analytics')
for table in list(analytics.models.values()):
self.assertTrue(table.objects.exists())
do_drop_all_analytics_tables()
for table in list(analytics.models.values()):
self.assertFalse(table.objects.exists())
class TestActiveUsersAudit(AnalyticsTestCase):
def setUp(self):
# type: () -> None
super(TestActiveUsersAudit, self).setUp()
self.user = self.create_user()
self.stat = COUNT_STATS['active_users_audit:is_bot:day']
self.current_property = self.stat.property
def add_event(self, event_type, days_offset, user=None):
# type: (str, float, Optional[UserProfile]) -> None
hours_offset = int(24*days_offset)
if user is None:
user = self.user
RealmAuditLog.objects.create(
realm=user.realm, modified_user=user, event_type=event_type,
event_time=self.TIME_ZERO - hours_offset*self.HOUR)
def test_user_deactivated_in_future(self):
# type: () -> None
self.add_event('user_created', 1)
self.add_event('user_deactivated', 0)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup'], [['false']])
def test_user_reactivated_in_future(self):
# type: () -> None
self.add_event('user_deactivated', 1)
self.add_event('user_reactivated', 0)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, [], [])
def test_user_active_then_deactivated_same_day(self):
# type: () -> None
self.add_event('user_created', 1)
self.add_event('user_deactivated', .5)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, [], [])
def test_user_unactive_then_activated_same_day(self):
# type: () -> None
self.add_event('user_deactivated', 1)
self.add_event('user_reactivated', .5)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup'], [['false']])
# Arguably these next two tests are duplicates of the _in_future tests, but are
# a guard against future refactorings where they may no longer be duplicates
def test_user_active_then_deactivated_with_day_gap(self):
# type: () -> None
self.add_event('user_created', 2)
self.add_event('user_deactivated', 1)
process_count_stat(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup', 'end_time'],
[['false', self.TIME_ZERO - self.DAY]])
def test_user_deactivated_then_reactivated_with_day_gap(self):
# type: () -> None
self.add_event('user_deactivated', 2)
self.add_event('user_reactivated', 1)
process_count_stat(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup'], [['false']])
def test_event_types(self):
# type: () -> None
self.add_event('user_created', 4)
self.add_event('user_deactivated', 3)
self.add_event('user_activated', 2)
self.add_event('user_reactivated', 1)
for i in range(4):
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO - i*self.DAY)
self.assertTableState(UserCount, ['subgroup', 'end_time'],
[['false', self.TIME_ZERO - i*self.DAY] for i in [3, 1, 0]])
# Also tests that aggregation to RealmCount and InstallationCount is
# being done, and that we're storing the user correctly in UserCount
def test_multiple_users_realms_and_bots(self):
# type: () -> None
user1 = self.create_user()
user2 = self.create_user()
second_realm = Realm.objects.create(string_id='moo', name='moo')
user3 = self.create_user(realm=second_realm)
user4 = self.create_user(realm=second_realm, is_bot=True)
for user in [user1, user2, user3, user4]:
self.add_event('user_created', 1, user=user)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup', 'user'],
[['false', user1], ['false', user2], ['false', user3], ['true', user4]])
self.assertTableState(RealmCount, ['value', 'subgroup', 'realm'],
[[2, 'false', self.default_realm], [1, 'false', second_realm],
[1, 'true', second_realm]])
self.assertTableState(InstallationCount, ['value', 'subgroup'], [[3, 'false'], [1, 'true']])
self.assertTableState(StreamCount, [], [])
# Not that interesting a test if you look at the SQL query at hand, but
# almost all other CountStats have a start_date, so guarding against a
# refactoring that adds that in.
# Also tests the slightly more end-to-end process_count_stat rather than
# do_fill_count_stat_at_hour. E.g. if one changes self.stat.frequency to
# CountStat.HOUR from CountStat.DAY, this will fail, while many of the
# tests above will not.
def test_update_from_two_days_ago(self):
# type: () -> None
self.add_event('user_created', 2)
process_count_stat(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup', 'end_time'],
[['false', self.TIME_ZERO], ['false', self.TIME_ZERO-self.DAY]])
# User with no relevant activity could happen e.g. for a system bot that
# doesn't go through do_create_user. Mainly just want to make sure that
# that situation doesn't throw an error.
def test_empty_realm_or_user_with_no_relevant_activity(self):
# type: () -> None
self.add_event('unrelated', 1)
self.create_user() # also test a user with no RealmAuditLog entries
Realm.objects.create(string_id='moo', name='moo')
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, [], [])
def test_max_audit_entry_is_unrelated(self):
# type: () -> None
self.add_event('user_created', 1)
self.add_event('unrelated', .5)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup'], [['false']])
# Simultaneous related audit entries should not be allowed, and so not testing for that.
def test_simultaneous_unrelated_audit_entry(self):
# type: () -> None
self.add_event('user_created', 1)
self.add_event('unrelated', 1)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['subgroup'], [['false']])
def test_simultaneous_max_audit_entries_of_different_users(self):
# type: () -> None
user1 = self.create_user()
user2 = self.create_user()
user3 = self.create_user()
self.add_event('user_created', .5, user=user1)
self.add_event('user_created', .5, user=user2)
self.add_event('user_created', 1, user=user3)
self.add_event('user_deactivated', .5, user=user3)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(UserCount, ['user', 'subgroup'],
[[user1, 'false'], [user2, 'false']])
def test_end_to_end_with_actions_dot_py(self):
# type: () -> None
user1 = do_create_user('email1', 'password', self.default_realm, 'full_name', 'short_name')
user2 = do_create_user('email2', 'password', self.default_realm, 'full_name', 'short_name')
user3 = do_create_user('email3', 'password', self.default_realm, 'full_name', 'short_name')
user4 = do_create_user('email4', 'password', self.default_realm, 'full_name', 'short_name')
do_deactivate_user(user2)
do_activate_user(user3)
do_reactivate_user(user4)
end_time = floor_to_day(timezone_now()) + self.DAY
do_fill_count_stat_at_hour(self.stat, end_time)
for user in [user1, user3, user4]:
self.assertTrue(UserCount.objects.filter(
user=user, property=self.current_property, subgroup='false',
end_time=end_time, value=1).exists())
self.assertFalse(UserCount.objects.filter(user=user2).exists())
class TestRealmActiveHumans(AnalyticsTestCase):
def setUp(self):
# type: () -> None
super(TestRealmActiveHumans, self).setUp()
self.stat = COUNT_STATS['realm_active_humans::day']
self.current_property = self.stat.property
def mark_audit_active(self, user, end_time=None):
# type: (UserProfile, Optional[datetime]) -> None
if end_time is None:
end_time = self.TIME_ZERO
UserCount.objects.create(
user=user, realm=user.realm, property='active_users_audit:is_bot:day',
subgroup=ujson.dumps(user.is_bot), end_time=end_time, value=1)
def mark_15day_active(self, user, end_time=None):
# type: (UserProfile, Optional[datetime]) -> None
if end_time is None:
end_time = self.TIME_ZERO
UserCount.objects.create(
user=user, realm=user.realm, property='15day_actives::day',
end_time=end_time, value=1)
def test_basic_boolean_logic(self):
# type: () -> None
user = self.create_user()
self.mark_audit_active(user, end_time=self.TIME_ZERO - self.DAY)
self.mark_15day_active(user, end_time=self.TIME_ZERO)
self.mark_audit_active(user, end_time=self.TIME_ZERO + self.DAY)
self.mark_15day_active(user, end_time=self.TIME_ZERO + self.DAY)
for i in [-1, 0, 1]:
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO + i*self.DAY)
self.assertTableState(RealmCount, ['value', 'end_time'], [[1, self.TIME_ZERO + self.DAY]])
def test_bots_not_counted(self):
# type: () -> None
bot = self.create_user(is_bot=True)
self.mark_audit_active(bot)
self.mark_15day_active(bot)
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO)
self.assertTableState(RealmCount, [], [])
def test_multiple_users_realms_and_times(self):
# type: () -> None
user1 = self.create_user()
user2 = self.create_user()
second_realm = Realm.objects.create(string_id='second', name='second')
user3 = self.create_user(realm=second_realm)
user4 = self.create_user(realm=second_realm)
user5 = self.create_user(realm=second_realm)
for user in [user1, user2, user3, user4, user5]:
self.mark_audit_active(user)
self.mark_15day_active(user)
for user in [user1, user3, user4]:
self.mark_audit_active(user, end_time=self.TIME_ZERO - self.DAY)
self.mark_15day_active(user, end_time=self.TIME_ZERO - self.DAY)
for i in [-1, 0, 1]:
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO + i*self.DAY)
self.assertTableState(RealmCount, ['value', 'realm', 'end_time'],
[[2, self.default_realm, self.TIME_ZERO],
[3, second_realm, self.TIME_ZERO],
[1, self.default_realm, self.TIME_ZERO - self.DAY],
[2, second_realm, self.TIME_ZERO - self.DAY]])
# Check that adding spurious entries doesn't make a difference
self.mark_audit_active(user1, end_time=self.TIME_ZERO + self.DAY)
self.mark_15day_active(user2, end_time=self.TIME_ZERO + self.DAY)
self.mark_15day_active(user2, end_time=self.TIME_ZERO - self.DAY)
self.create_user()
third_realm = Realm.objects.create(string_id='third', name='third')
self.create_user(realm=third_realm)
RealmCount.objects.all().delete()
for i in [-1, 0, 1]:
do_fill_count_stat_at_hour(self.stat, self.TIME_ZERO + i*self.DAY)
self.assertTableState(RealmCount, ['value', 'realm', 'end_time'],
[[2, self.default_realm, self.TIME_ZERO],
[3, second_realm, self.TIME_ZERO],
[1, self.default_realm, self.TIME_ZERO - self.DAY],
[2, second_realm, self.TIME_ZERO - self.DAY]])
def test_end_to_end(self):
# type: () -> None
user1 = do_create_user('email1', 'password', self.default_realm, 'full_name', 'short_name')
user2 = do_create_user('email2', 'password', self.default_realm, 'full_name', 'short_name')
do_create_user('email3', 'password', self.default_realm, 'full_name', 'short_name')
time_zero = floor_to_day(timezone_now()) + self.DAY
update_user_activity_interval(user1, time_zero)
update_user_activity_interval(user2, time_zero)
do_deactivate_user(user2)
for property in ['active_users_audit:is_bot:day', '15day_actives::day',
'realm_active_humans::day']:
FillState.objects.create(property=property, state=FillState.DONE, end_time=time_zero)
process_count_stat(COUNT_STATS[property], time_zero+self.DAY)
self.assertEqual(RealmCount.objects.filter(
property='realm_active_humans::day', end_time=time_zero+self.DAY, value=1).count(), 1)
self.assertEqual(RealmCount.objects.filter(property='realm_active_humans::day').count(), 1)

View File

@@ -0,0 +1,31 @@
from zerver.lib.test_classes import ZulipTestCase
from analytics.lib.counts import CountStat
from analytics.lib.fixtures import generate_time_series_data
# A very light test suite; the code being tested is not run in production.
class TestFixtures(ZulipTestCase):
def test_deterministic_settings(self):
# type: () -> None
# test basic business_hour / non_business_hour calculation
# test we get an array of the right length with frequency=CountStat.DAY
data = generate_time_series_data(
days=7, business_hours_base=20, non_business_hours_base=15, spikiness=0)
self.assertEqual(data, [400, 400, 400, 400, 400, 360, 360])
data = generate_time_series_data(
days=1, business_hours_base=2000, non_business_hours_base=1500,
growth=2, spikiness=0, frequency=CountStat.HOUR)
# test we get an array of the right length with frequency=CountStat.HOUR
self.assertEqual(len(data), 24)
# test that growth doesn't affect the first data point
self.assertEqual(data[0], 2000)
# test that the last data point is growth times what it otherwise would be
self.assertEqual(data[-1], 1500*2)
# test autocorrelation == 1, since that's the easiest value to test
data = generate_time_series_data(
days=1, business_hours_base=2000, non_business_hours_base=2000,
autocorrelation=1, frequency=CountStat.HOUR)
self.assertEqual(data[0], data[1])
self.assertEqual(data[0], data[-1])

View File

@@ -1,18 +1,283 @@
from django.utils.timezone import get_fixed_timezone
from zerver.lib.test_classes import ZulipTestCase
from __future__ import absolute_import
from analytics.lib.counts import CountStat
from django.utils.timezone import get_fixed_timezone, utc
from zerver.lib.test_classes import ZulipTestCase
from zerver.lib.timestamp import ceiling_to_hour, ceiling_to_day, \
datetime_to_timestamp
from zerver.models import Realm, UserProfile, Client, get_realm, \
get_user_profile_by_email
from analytics.lib.counts import CountStat, COUNT_STATS
from analytics.lib.time_utils import time_range
from analytics.views import rewrite_client_arrays
from analytics.models import RealmCount, UserCount, BaseCount, \
FillState, last_successful_fill
from analytics.views import stats, get_chart_data, sort_by_totals, \
sort_client_labels, rewrite_client_arrays
from datetime import datetime, timedelta
import mock
import ujson
from six.moves import range
from typing import List, Dict, Optional
class TestStatsEndpoint(ZulipTestCase):
def test_stats(self):
# type: () -> None
self.user = get_user_profile_by_email('hamlet@zulip.com')
self.login(self.user.email)
result = self.client_get('/stats')
self.assertEqual(result.status_code, 200)
# Check that we get something back
self.assert_in_response("Zulip Analytics for", result)
class TestGetChartData(ZulipTestCase):
def setUp(self):
# type: () -> None
self.realm = get_realm('zulip')
self.user = get_user_profile_by_email('hamlet@zulip.com')
self.login(self.user.email)
self.end_times_hour = [ceiling_to_hour(self.realm.date_created) + timedelta(hours=i)
for i in range(4)]
self.end_times_day = [ceiling_to_day(self.realm.date_created) + timedelta(days=i)
for i in range(4)]
def data(self, i):
# type: (int) -> List[int]
return [0, 0, i, 0]
def insert_data(self, stat, realm_subgroups, user_subgroups):
# type: (CountStat, List[Optional[str]], List[str]) -> None
if stat.frequency == CountStat.HOUR:
insert_time = self.end_times_hour[2]
fill_time = self.end_times_hour[-1]
if stat.frequency == CountStat.DAY:
insert_time = self.end_times_day[2]
fill_time = self.end_times_day[-1]
RealmCount.objects.bulk_create([
RealmCount(property=stat.property, subgroup=subgroup, end_time=insert_time,
value=100+i, realm=self.realm)
for i, subgroup in enumerate(realm_subgroups)])
UserCount.objects.bulk_create([
UserCount(property=stat.property, subgroup=subgroup, end_time=insert_time,
value=200+i, realm=self.realm, user=self.user)
for i, subgroup in enumerate(user_subgroups)])
FillState.objects.create(property=stat.property, end_time=fill_time, state=FillState.DONE)
def test_number_of_humans(self):
# type: () -> None
stat = COUNT_STATS['realm_active_humans::day']
self.insert_data(stat, [None], [])
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data, {
'msg': '',
'end_times': [datetime_to_timestamp(dt) for dt in self.end_times_day],
'frequency': CountStat.DAY,
'realm': {'human': self.data(100)},
'display_order': None,
'result': 'success',
})
def test_messages_sent_over_time(self):
# type: () -> None
stat = COUNT_STATS['messages_sent:is_bot:hour']
self.insert_data(stat, ['true', 'false'], ['false'])
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'messages_sent_over_time'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data, {
'msg': '',
'end_times': [datetime_to_timestamp(dt) for dt in self.end_times_hour],
'frequency': CountStat.HOUR,
'realm': {'bot': self.data(100), 'human': self.data(101)},
'user': {'bot': self.data(0), 'human': self.data(200)},
'display_order': None,
'result': 'success',
})
def test_messages_sent_by_message_type(self):
# type: () -> None
stat = COUNT_STATS['messages_sent:message_type:day']
self.insert_data(stat, ['public_stream', 'private_message'],
['public_stream', 'private_stream'])
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'messages_sent_by_message_type'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data, {
'msg': '',
'end_times': [datetime_to_timestamp(dt) for dt in self.end_times_day],
'frequency': CountStat.DAY,
'realm': {'Public streams': self.data(100), 'Private streams': self.data(0),
'Private messages': self.data(101), 'Group private messages': self.data(0)},
'user': {'Public streams': self.data(200), 'Private streams': self.data(201),
'Private messages': self.data(0), 'Group private messages': self.data(0)},
'display_order': ['Private messages', 'Public streams', 'Private streams', 'Group private messages'],
'result': 'success',
})
def test_messages_sent_by_client(self):
# type: () -> None
stat = COUNT_STATS['messages_sent:client:day']
client1 = Client.objects.create(name='client 1')
client2 = Client.objects.create(name='client 2')
client3 = Client.objects.create(name='client 3')
client4 = Client.objects.create(name='client 4')
self.insert_data(stat, [client4.id, client3.id, client2.id],
[client3.id, client1.id])
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'messages_sent_by_client'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data, {
'msg': '',
'end_times': [datetime_to_timestamp(dt) for dt in self.end_times_day],
'frequency': CountStat.DAY,
'realm': {'client 4': self.data(100), 'client 3': self.data(101),
'client 2': self.data(102)},
'user': {'client 3': self.data(200), 'client 1': self.data(201)},
'display_order': ['client 1', 'client 2', 'client 3', 'client 4'],
'result': 'success',
})
def test_include_empty_subgroups(self):
# type: () -> None
FillState.objects.create(
property='realm_active_humans::day', end_time=self.end_times_day[0], state=FillState.DONE)
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data['realm'], {'human': [0]})
self.assertFalse('user' in data)
FillState.objects.create(
property='messages_sent:is_bot:hour', end_time=self.end_times_hour[0], state=FillState.DONE)
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'messages_sent_over_time'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data['realm'], {'human': [0], 'bot': [0]})
self.assertEqual(data['user'], {'human': [0], 'bot': [0]})
FillState.objects.create(
property='messages_sent:message_type:day', end_time=self.end_times_day[0], state=FillState.DONE)
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'messages_sent_by_message_type'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data['realm'], {
'Public streams': [0], 'Private streams': [0], 'Private messages': [0], 'Group private messages': [0]})
self.assertEqual(data['user'], {
'Public streams': [0], 'Private streams': [0], 'Private messages': [0], 'Group private messages': [0]})
FillState.objects.create(
property='messages_sent:client:day', end_time=self.end_times_day[0], state=FillState.DONE)
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'messages_sent_by_client'})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data['realm'], {})
self.assertEqual(data['user'], {})
def test_start_and_end(self):
# type: () -> None
stat = COUNT_STATS['realm_active_humans::day']
self.insert_data(stat, [None], [])
end_time_timestamps = [datetime_to_timestamp(dt) for dt in self.end_times_day]
# valid start and end
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans',
'start': end_time_timestamps[1],
'end': end_time_timestamps[2]})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data['end_times'], end_time_timestamps[1:3])
self.assertEqual(data['realm'], {'human': [0, 100]})
# start later then end
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans',
'start': end_time_timestamps[2],
'end': end_time_timestamps[1]})
self.assert_json_error_contains(result, 'Start time is later than')
def test_min_length(self):
# type: () -> None
stat = COUNT_STATS['realm_active_humans::day']
self.insert_data(stat, [None], [])
# test min_length is too short to change anything
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans',
'min_length': 2})
self.assert_json_success(result)
data = ujson.loads(result.content)
self.assertEqual(data['end_times'], [datetime_to_timestamp(dt) for dt in self.end_times_day])
self.assertEqual(data['realm'], {'human': self.data(100)})
# test min_length larger than filled data
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans',
'min_length': 5})
self.assert_json_success(result)
data = ujson.loads(result.content)
end_times = [ceiling_to_day(self.realm.date_created) + timedelta(days=i) for i in range(-1, 4)]
self.assertEqual(data['end_times'], [datetime_to_timestamp(dt) for dt in end_times])
self.assertEqual(data['realm'], {'human': [0]+self.data(100)})
def test_non_existent_chart(self):
# type: () -> None
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'does_not_exist'})
self.assert_json_error_contains(result, 'Unknown chart name')
def test_analytics_not_running(self):
# type: () -> None
# try to get data for a valid chart, but before we've put anything in the database
# (e.g. before update_analytics_counts has been run)
with mock.patch('logging.warning'):
result = self.client_get('/json/analytics/chart_data',
{'chart_name': 'number_of_humans'})
self.assert_json_error_contains(result, 'No analytics data available')
class TestGetChartDataHelpers(ZulipTestCase):
# last_successful_fill is in analytics/models.py, but get_chart_data is
# the only function that uses it at the moment
def test_last_successful_fill(self):
# type: () -> None
self.assertIsNone(last_successful_fill('non-existant'))
a_time = datetime(2016, 3, 14, 19).replace(tzinfo=utc)
one_hour_before = datetime(2016, 3, 14, 18).replace(tzinfo=utc)
fillstate = FillState.objects.create(property='property', end_time=a_time,
state=FillState.DONE)
self.assertEqual(last_successful_fill('property'), a_time)
fillstate.state = FillState.STARTED
fillstate.save()
self.assertEqual(last_successful_fill('property'), one_hour_before)
def test_sort_by_totals(self):
# type: () -> None
empty = [] # type: List[int]
value_arrays = {'c': [0, 1], 'a': [9], 'b': [1, 1, 1], 'd': empty}
self.assertEqual(sort_by_totals(value_arrays), ['a', 'b', 'c', 'd'])
def test_sort_client_labels(self):
# type: () -> None
data = {'realm': {'a': [16], 'c': [15], 'b': [14], 'e': [13], 'd': [12], 'h': [11]},
'user': {'a': [6], 'b': [5], 'd': [4], 'e': [3], 'f': [2], 'g': [1]}}
self.assertEqual(sort_client_labels(data), ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'])
class TestTimeRange(ZulipTestCase):
def test_time_range(self):
# type: () -> None
HOUR = timedelta(hours=1)
DAY = timedelta(days=1)
TZINFO = get_fixed_timezone(-100) # 100 minutes west of UTC
TZINFO = get_fixed_timezone(-100) # 100 minutes west of UTC
# Using 22:59 so that converting to UTC and applying floor_to_{hour,day} do not commute
a_time = datetime(2016, 3, 14, 22, 59).replace(tzinfo=TZINFO)

View File

@@ -1,45 +1,49 @@
from __future__ import absolute_import, division
from django.conf import settings
from django.core import urlresolvers
from django.db import connection
from django.db.models import Sum
from django.db.models.query import QuerySet
from django.http import HttpResponseNotFound, HttpRequest, HttpResponse
from django.template import RequestContext, loader
from django.utils import timezone
from django.utils.timezone import now as timezone_now
from django.utils.translation import ugettext as _
from django.shortcuts import render
from jinja2 import Markup as mark_safe
from analytics.lib.counts import CountStat, process_count_stat, COUNT_STATS
from analytics.lib.time_utils import time_range
from analytics.models import BaseCount, InstallationCount, RealmCount, \
UserCount, StreamCount
UserCount, StreamCount, last_successful_fill
from zerver.decorator import has_request_variables, REQ, zulip_internal, \
from zerver.decorator import has_request_variables, REQ, require_server_admin, \
zulip_login_required, to_non_negative_int, to_utc_datetime
from zerver.lib.request import JsonableError
from zerver.lib.response import json_success
from zerver.lib.timestamp import ceiling_to_hour, ceiling_to_day, timestamp_to_datetime
from zerver.models import Realm, UserProfile, UserActivity, \
UserActivityInterval, Client
from zproject.jinja2 import render_to_response
from collections import defaultdict
from datetime import datetime, timedelta
import itertools
import json
import logging
import pytz
import re
import time
from six.moves import filter, map, range, zip
from typing import Any, Dict, List, Tuple, Optional, Sequence, Callable, Type, \
Union, Text
from typing import Any, Callable, Dict, List, Optional, Set, Text, \
Tuple, Type, Union
@zulip_login_required
def stats(request):
# type: (HttpRequest) -> HttpResponse
return render_to_response('analytics/stats.html')
return render(request,
'analytics/stats.html',
context=dict(realm_name = request.user.realm.name))
@has_request_variables
def get_chart_data(request, user_profile, chart_name=REQ(),
@@ -47,54 +51,94 @@ def get_chart_data(request, user_profile, chart_name=REQ(),
start=REQ(converter=to_utc_datetime, default=None),
end=REQ(converter=to_utc_datetime, default=None)):
# type: (HttpRequest, UserProfile, Text, Optional[int], Optional[datetime], Optional[datetime]) -> HttpResponse
realm = user_profile.realm
# These are implicitly relying on realm.date_created and timezone.now being in UTC.
if start is None:
start = realm.date_created
if end is None:
end = timezone.now()
if start > end:
raise JsonableError(_("Start time is later than end time. Start: %(start)s, End: %(end)s") %
{'start': start, 'end': end})
if chart_name == 'number_of_humans':
stat = COUNT_STATS['active_users:is_bot:day']
stat = COUNT_STATS['realm_active_humans::day']
tables = [RealmCount]
subgroups = ['false', 'true']
labels = ['human', 'bot']
subgroup_to_label = {None: 'human'} # type: Dict[Optional[str], str]
labels_sort_function = None
include_empty_subgroups = True
elif chart_name == 'messages_sent_over_time':
stat = COUNT_STATS['messages_sent:is_bot:hour']
tables = [RealmCount]
subgroups = ['false', 'true']
labels = ['human', 'bot']
tables = [RealmCount, UserCount]
subgroup_to_label = {'false': 'human', 'true': 'bot'}
labels_sort_function = None
include_empty_subgroups = True
elif chart_name == 'messages_sent_by_message_type':
stat = COUNT_STATS['messages_sent:message_type:day']
tables = [RealmCount, UserCount]
subgroups = ['public_stream', 'private_stream', 'private_message']
labels = None
subgroup_to_label = {'public_stream': 'Public streams',
'private_stream': 'Private streams',
'private_message': 'Private messages',
'huddle_message': 'Group private messages'}
labels_sort_function = lambda data: sort_by_totals(data['realm'])
include_empty_subgroups = True
elif chart_name == 'messages_sent_by_client':
stat = COUNT_STATS['messages_sent:client:day']
tables = [RealmCount, UserCount]
subgroups = [str(x) for x in Client.objects.values_list('id', flat=True).order_by('id')]
labels = list(Client.objects.values_list('name', flat=True).order_by('id'))
# Note that the labels are further re-written by client_label_map
subgroup_to_label = {str(id): name for id, name in Client.objects.values_list('id', 'name')}
labels_sort_function = sort_client_labels
include_empty_subgroups = False
else:
raise JsonableError(_("Unknown chart name: %s") % (chart_name,))
# Most likely someone using our API endpoint. The /stats page does not
# pass a start or end in its requests.
if start is not None and end is not None and start > end:
raise JsonableError(_("Start time is later than end time. Start: %(start)s, End: %(end)s") %
{'start': start, 'end': end})
realm = user_profile.realm
if start is None:
start = realm.date_created
if end is None:
end = last_successful_fill(stat.property)
if end is None or start > end:
logging.warning("User from realm %s attempted to access /stats, but the computed "
"start time: %s (creation time of realm) is later than the computed "
"end time: %s (last successful analytics update). Is the "
"analytics cron job running?" % (realm.string_id, start, end))
raise JsonableError(_("No analytics data available. Please contact your server administrator."))
end_times = time_range(start, end, stat.frequency, min_length)
data = {'end_times': end_times, 'frequency': stat.frequency, 'interval': stat.interval}
data = {'end_times': end_times, 'frequency': stat.frequency}
for table in tables:
if table == RealmCount:
data['realm'] = get_time_series_by_subgroup(
stat, RealmCount, realm.id, end_times, subgroups, labels, include_empty_subgroups)
stat, RealmCount, realm.id, end_times, subgroup_to_label, include_empty_subgroups)
if table == UserCount:
data['user'] = get_time_series_by_subgroup(
stat, UserCount, user_profile.id, end_times, subgroups, labels, include_empty_subgroups)
stat, UserCount, user_profile.id, end_times, subgroup_to_label, include_empty_subgroups)
if labels_sort_function is not None:
data['display_order'] = labels_sort_function(data)
else:
data['display_order'] = None
return json_success(data=data)
def sort_by_totals(value_arrays):
# type: (Dict[str, List[int]]) -> List[str]
totals = [(sum(values), label) for label, values in value_arrays.items()]
totals.sort(reverse=True)
return [label for total, label in totals]
# For any given user, we want to show a fixed set of clients in the chart,
# regardless of the time aggregation or whether we're looking at realm or
# user data. This fixed set ideally includes the clients most important in
# understanding the realm's traffic and the user's traffic. This function
# tries to rank the clients so that taking the first N elements of the
# sorted list has a reasonable chance of doing so.
def sort_client_labels(data):
# type: (Dict[str, Dict[str, List[int]]]) -> List[str]
realm_order = sort_by_totals(data['realm'])
user_order = sort_by_totals(data['user'])
label_sort_values = {} # type: Dict[str, float]
for i, label in enumerate(realm_order):
label_sort_values[label] = i
for i, label in enumerate(user_order):
label_sort_values[label] = min(i-.1, label_sort_values.get(label, i))
return [label for label, sort_value in sorted(label_sort_values.items(),
key=lambda x: x[1])]
def table_filtered_to_id(table, key_id):
# type: (Type[BaseCount], int) -> QuerySet
if table == RealmCount:
@@ -106,7 +150,7 @@ def table_filtered_to_id(table, key_id):
elif table == InstallationCount:
return InstallationCount.objects.all()
else:
raise ValueError("Unknown table: %s" % (table,))
raise AssertionError("Unknown table: %s" % (table,))
def client_label_map(name):
# type: (str) -> str
@@ -128,7 +172,7 @@ def client_label_map(name):
def rewrite_client_arrays(value_arrays):
# type: (Dict[str, List[int]]) -> Dict[str, List[int]]
mapped_arrays = {} # type: Dict[str, List[int]]
mapped_arrays = {} # type: Dict[str, List[int]]
for label, array in value_arrays.items():
mapped_label = client_label_map(label)
if mapped_label in mapped_arrays:
@@ -138,20 +182,15 @@ def rewrite_client_arrays(value_arrays):
mapped_arrays[mapped_label] = [value_arrays[label][i] for i in range(0, len(array))]
return mapped_arrays
def get_time_series_by_subgroup(stat, table, key_id, end_times, subgroups, labels, include_empty_subgroups):
# type: (CountStat, Type[BaseCount], Optional[int], List[datetime], List[str], Optional[List[str]], bool) -> Dict[str, List[int]]
if labels is None:
labels = subgroups
if len(subgroups) != len(labels):
raise ValueError("subgroups and labels have lengths %s and %s, which are different." %
(len(subgroups), len(labels)))
def get_time_series_by_subgroup(stat, table, key_id, end_times, subgroup_to_label, include_empty_subgroups):
# type: (CountStat, Type[BaseCount], int, List[datetime], Dict[Optional[str], str], bool) -> Dict[str, List[int]]
queryset = table_filtered_to_id(table, key_id).filter(property=stat.property) \
.values_list('subgroup', 'end_time', 'value')
value_dicts = defaultdict(lambda: defaultdict(int)) # type: Dict[Optional[str], Dict[datetime, int]]
value_dicts = defaultdict(lambda: defaultdict(int)) # type: Dict[Optional[str], Dict[datetime, int]]
for subgroup, end_time, value in queryset:
value_dicts[subgroup][end_time] = value
value_arrays = {}
for subgroup, label in zip(subgroups, labels):
for subgroup, label in subgroup_to_label.items():
if (subgroup in value_dicts) or include_empty_subgroups:
value_arrays[label] = [value_dicts[subgroup][end_time] for end_time in end_times]
@@ -222,7 +261,7 @@ def get_realm_day_counts():
rows = dictfetchall(cursor)
cursor.close()
counts = defaultdict(dict) # type: Dict[str, Dict[int, int]]
counts = defaultdict(dict) # type: Dict[str, Dict[int, int]]
for row in rows:
counts[row['string_id']][row['age']] = row['cnt']
@@ -702,12 +741,12 @@ def ad_hoc_queries():
return pages
@zulip_internal
@require_server_admin
@has_request_variables
def get_activity(request):
# type: (HttpRequest) -> HttpResponse
duration_content, realm_minutes = user_activity_intervals() # type: Tuple[mark_safe, Dict[str, float]]
counts_content = realm_summary_table(realm_minutes) # type: str
duration_content, realm_minutes = user_activity_intervals() # type: Tuple[mark_safe, Dict[str, float]]
counts_content = realm_summary_table(realm_minutes) # type: str
data = [
('Counts', counts_content),
('Durations', duration_content),
@@ -717,10 +756,10 @@ def get_activity(request):
title = 'Activity'
return render_to_response(
return render(
request,
'analytics/activity.html',
dict(data=data, title=title, is_home=True),
request=request
context=dict(data=data, title=title, is_home=True),
)
def get_user_activity_records_for_realm(realm, is_bot):
@@ -789,7 +828,7 @@ def get_user_activity_summary(records):
#: We could use something like:
# `Union[Dict[str, Dict[str, int]], Dict[str, Dict[str, datetime]]]`
#: but that would require this long `Union` to carry on throughout inner functions.
summary = {} # type: Dict[str, Dict[str, Any]]
summary = {} # type: Dict[str, Dict[str, Any]]
def update(action, record):
# type: (str, QuerySet) -> None
@@ -952,7 +991,7 @@ def realm_user_summary_table(all_records, admin_emails):
def is_recent(val):
# type: (Optional[datetime]) -> bool
age = datetime.now(val.tzinfo) - val
age = timezone_now() - val
return age.total_seconds() < 5 * 60
rows = []
@@ -974,7 +1013,7 @@ def realm_user_summary_table(all_records, admin_emails):
rows.append(row)
def by_used_time(row):
# type: (Dict[str, Sequence[str]]) -> str
# type: (Dict[str, Any]) -> str
return row['cells'][3]
rows = sorted(rows, key=by_used_time, reverse=True)
@@ -996,11 +1035,11 @@ def realm_user_summary_table(all_records, admin_emails):
content = make_table(title, cols, rows, has_row_class=True)
return user_records, content
@zulip_internal
@require_server_admin
def get_realm_activity(request, realm_str):
# type: (HttpRequest, str) -> HttpResponse
data = [] # type: List[Tuple[str, str]]
all_user_records = {} # type: Dict[str, Any]
data = [] # type: List[Tuple[str, str]]
all_user_records = {} # type: Dict[str, Any]
try:
admins = Realm.objects.get(string_id=realm_str).get_admin_users()
@@ -1029,18 +1068,18 @@ def get_realm_activity(request, realm_str):
realm_link += '&target=stats.gauges.staging.users.active.%s.0_16hr' % (realm_str,)
title = realm_str
return render_to_response(
return render(
request,
'analytics/activity.html',
dict(data=data, realm_link=realm_link, title=title),
request=request
context=dict(data=data, realm_link=realm_link, title=title),
)
@zulip_internal
@require_server_admin
def get_user_activity(request, email):
# type: (HttpRequest, str) -> HttpResponse
records = get_user_activity_records_for_email(email)
data = [] # type: List[Tuple[str, str]]
data = [] # type: List[Tuple[str, str]]
user_summary = get_user_activity_summary(records)
content = user_activity_summary_table(user_summary)
@@ -1050,8 +1089,8 @@ def get_user_activity(request, email):
data += [('Info', content)]
title = email
return render_to_response(
return render(
request,
'analytics/activity.html',
dict(data=data, title=title),
request=request
context=dict(data=data, title=title),
)

View File

@@ -44,7 +44,12 @@ Alternatively, you may explicitly use "--user", "--api-key", and
`--site` in our examples, which is especially useful when testing. If
you are running several bots which share a home directory, we
recommend using `--config` to specify the path to the `zuliprc` file
for a specific bot.
for a specific bot. Finally, you can control the defaults for all of
these variables using the environment variables `ZULIP_CONFIG`,
`ZULIP_API_KEY`, `ZULIP_EMAIL`, `ZULIP_SITE`, `ZULIP_CERT`,
`ZULIP_CERT_KEY`, and `ZULIP_CERT_BUNDLE`. Command-line options take
precedence over environment variables take precedence over the config
files.
The command line equivalents for other configuration options are:

View File

@@ -6,13 +6,13 @@ from os.path import expanduser
from six.moves import configparser as cp
home = expanduser('~')
CONFIG_PATH = home + '/google-commute.ini'
CONFIG_PATH = home + '/commute.config'
class CommuteHandler(object):
'''
This plugin provides information regarding commuting
from an origin to a destination, providing a multitude of information.
It looks for messages starting with '@commute'.
It looks for messages starting with @mention of the bot.
'''
def __init__(self):
@@ -25,7 +25,7 @@ class CommuteHandler(object):
It can vary outputs depending on traffic conditions, departure and
arrival times as well as user preferences
(toll avoidance, preference for bus travel, etc.).
It looks for messages starting with '@commute'.
It looks for messages starting with @mention of the bot.
Users should input an origin and a destination
in any stream or through private messages to the bot to receive a
@@ -33,8 +33,8 @@ class CommuteHandler(object):
input was originally private.
Sample input:
@commute origins=Chicago,IL,USA destinations=New+York,NY,USA
@commute help
@mention-botname origins=Chicago,IL,USA destinations=New+York,NY,USA
@mention-botname help
'''
help_info = '''
@@ -58,7 +58,7 @@ class CommuteHandler(object):
e.g. language=fr
Sample request:
@commute origins=Chicago,IL,USA destinations=New+York,NY,USA language=fr
@mention-botname origins=Chicago,IL,USA destinations=New+York,NY,USA language=fr
Please note:
Fare information can be derived, though is solely dependent on the
@@ -77,22 +77,12 @@ class CommuteHandler(object):
you can use the timezone bot.
'''
def triage_message(self, message, client):
original_content = message['content']
# This next line of code is defensive, as we
# never want to get into an infinite loop of posting follow
# ups for own follow ups!
if message['display_recipient'] == 'commute':
return False
is_commute = original_content.startswith('@commute')
return is_commute
# adds API Authentication Key to url request
def get_api_key(self):
# google-commute.ini must have been moved from
# ~/zulip/contrib_bots/bots/commute_bot/CommuteBot/google-commute.ini into
# /google-commute.ini for program to work
# see doc.md for more information
# commute.config must be moved from
# ~/zulip/api/bots/commute/commute.config into
# ~/commute.config for program to work
# see readme.md for more information
with open(CONFIG_PATH) as settings:
config = cp.ConfigParser()
config.readfp(settings)
@@ -100,19 +90,7 @@ class CommuteHandler(object):
# determines if bot will respond as a private message/ stream message
def send_info(self, message, letter, client):
if message['type'] == 'private':
client.send_message(dict(
type='private',
to=message['sender_email'],
content=letter,
))
else:
client.send_message(dict(
type='stream',
subject=message['subject'],
to=message['display_recipient'],
content=letter,
))
client.send_reply(message, letter)
def calculate_seconds(self, time_str):
times = time_str.split(',')
@@ -220,13 +198,13 @@ class CommuteHandler(object):
def handle_message(self, message, client, state_handler):
original_content = message['content']
content_list = original_content.split()
query = original_content.split()
if "help" in content_list:
if "help" in query:
self.send_info(message, self.help_info, client)
return
params = self.parse_pair(content_list)
params = self.parse_pair(query)
params['key'] = self.api_key
self.add_time_to_params(params)

View File

@@ -11,24 +11,24 @@ units and information in various languages.
The bot will respond to the same stream input was in. And if called as
private message, the bot will reply with a private message.
To setup the bot, you will first need to move google-commute.ini into
To setup the bot, you will first need to move commute.config into
the user home directory and add an API key.
Move
```
~/zulip/contrib_bots/bots/commute_bot/CommuteBot/google-commute.ini
~/zulip/api/bots/commute/commute.config
```
into
```
~/google-commute.ini
~/commute.config
```
To add an API key, please visit:
https://developers.google.com/maps/documentation/distance-matrix/start
to retrieve a key and copy your api key into google-commute.ini
to retrieve a key and copy your api key into commute.config
Sample input and output:

View File

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -0,0 +1,130 @@
# See readme.md for instructions on running this code.
from __future__ import absolute_import
from __future__ import division
import copy
import importlib
import sys
from math import log10, floor
import utils
import re
def is_float(value):
try:
float(value)
return True
except ValueError:
return False
# Rounds the number 'x' to 'digits' significant digits.
# A normal 'round()' would round the number to an absolute amount of
# fractional decimals, e.g. 0.00045 would become 0.0.
# 'round_to()' rounds only the digits that are not 0.
# 0.00045 would then become 0.0005.
def round_to(x, digits):
return round(x, digits-int(floor(log10(abs(x)))))
class ConverterHandler(object):
'''
This plugin allows users to make conversions between various units,
e.g. Celsius to Fahrenheit, or kilobytes to gigabytes.
It looks for messages of the format
'@mention-bot <number> <unit_from> <unit_to>'
The message '@mention-bot help' posts a short description of how to use
the plugin, along with a list of all supported units.
'''
def usage(self):
return '''
This plugin allows users to make conversions between
various units, e.g. Celsius to Fahrenheit,
or kilobytes to gigabytes. It looks for messages of
the format '@mention-bot <number> <unit_from> <unit_to>'
The message '@mention-bot help' posts a short description of
how to use the plugin, along with a list of
all supported units.
'''
def handle_message(self, message, client, state_handler):
bot_response = get_bot_converter_response(message, client)
client.send_reply(message, bot_response)
def get_bot_converter_response(message, client):
content = message['content']
words = content.lower().split()
convert_indexes = [i for i, word in enumerate(words) if word == "@convert"]
convert_indexes = [-1] + convert_indexes
results = []
for convert_index in convert_indexes:
if (convert_index + 1) < len(words) and words[convert_index + 1] == 'help':
results.append(utils.HELP_MESSAGE)
continue
if (convert_index + 3) < len(words):
number = words[convert_index + 1]
unit_from = utils.ALIASES.get(words[convert_index + 2], words[convert_index + 2])
unit_to = utils.ALIASES.get(words[convert_index + 3], words[convert_index + 3])
exponent = 0
if not is_float(number):
results.append(number + ' is not a valid number. ' + utils.QUICK_HELP)
continue
number = float(number)
number_res = copy.copy(number)
for key, exp in utils.PREFIXES.items():
if unit_from.startswith(key):
exponent += exp
unit_from = unit_from[len(key):]
if unit_to.startswith(key):
exponent -= exp
unit_to = unit_to[len(key):]
uf_to_std = utils.UNITS.get(unit_from, False)
ut_to_std = utils.UNITS.get(unit_to, False)
if uf_to_std is False:
results.append(unit_from + ' is not a valid unit. ' + utils.QUICK_HELP)
if ut_to_std is False:
results.append(unit_to + ' is not a valid unit.' + utils.QUICK_HELP)
if uf_to_std is False or ut_to_std is False:
continue
base_unit = uf_to_std[2]
if uf_to_std[2] != ut_to_std[2]:
unit_from = unit_from.capitalize() if uf_to_std[2] == 'kelvin' else unit_from
results.append(unit_to.capitalize() + ' and ' + unit_from +
' are not from the same category. ' + utils.QUICK_HELP)
continue
# perform the conversion between the units
number_res *= uf_to_std[1]
number_res += uf_to_std[0]
number_res -= ut_to_std[0]
number_res /= ut_to_std[1]
if base_unit == 'bit':
number_res *= 1024 ** (exponent // 3)
else:
number_res *= 10 ** exponent
number_res = round_to(number_res, 7)
results.append('{} {} = {} {}'.format(number,
words[convert_index + 2],
number_res,
words[convert_index + 3]))
else:
results.append('Too few arguments given. ' + utils.QUICK_HELP)
new_content = ''
for idx, result in enumerate(results, 1):
new_content += ((str(idx) + '. conversion: ') if len(results) > 1 else '') + result + '\n'
return new_content
handler_class = ConverterHandler

View File

@@ -0,0 +1,30 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestConverterBot(BotTestCase):
bot_name = "converter"
def test_bot(self):
expected = {
"": ('Too few arguments given. Enter `@convert help` '
'for help on using the converter.\n'),
"foo bar": ('Too few arguments given. Enter `@convert help` '
'for help on using the converter.\n'),
"2 m cm": "2.0 m = 200.0 cm\n",
"12.0 celsius fahrenheit": "12.0 celsius = 53.600054 fahrenheit\n",
"0.002 kilometer millimile": "0.002 kilometer = 1.2427424 millimile\n",
"3 megabyte kilobit": "3.0 megabyte = 24576.0 kilobit\n",
}
self.check_expected_responses(expected)

View File

View File

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 73 KiB

View File

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -7,7 +7,7 @@ import html2text
class DefineHandler(object):
'''
This plugin define a word that the user inputs. It
looks for messages starting with '@define'.
looks for messages starting with '@mention-bot'.
'''
DEFINITION_API_URL = 'https://owlbot.info/api/v1/dictionary/{}?format=json'
@@ -15,70 +15,52 @@ class DefineHandler(object):
EMPTY_WORD_REQUEST_ERROR_MESSAGE = 'Please enter a word to define.'
PHRASE_ERROR_MESSAGE = 'Definitions for phrases are not available.'
def usage(DefineHandler):
def usage(self):
return '''
This plugin will allow users to define a word. Users should preface
messages with "@define".
messages with @mention-bot.
'''
def triage_message(DefineHandler, message, client):
original_content = message['content']
# This next line of code is defensive, as we
# never want to get into an infinite loop of posting follow
# ups for own follow ups!
is_define = original_content.startswith('@define')
def handle_message(self, message, client, state_handler):
original_content = message['content'].strip()
bot_response = self.get_bot_define_response(original_content)
return is_define
client.send_reply(message, bot_response)
def _handle_definition(DefineHandler, original_content):
# Remove '@define' from the message and extract the rest of the message, the
# word to define.
def get_bot_define_response(self, original_content):
split_content = original_content.split(' ')
# If there are more than one word (a phrase)
if len(split_content) > 2:
if len(split_content) > 1:
return DefineHandler.PHRASE_ERROR_MESSAGE
to_define = split_content[1].strip()
to_define = split_content[0].strip()
to_define_lower = to_define.lower()
# No word was entered.
if not to_define_lower:
return DefineHandler.EMPTY_WORD_REQUEST_ERROR_MESSAGE
return self.EMPTY_WORD_REQUEST_ERROR_MESSAGE
else:
response = '**{}**:\n'.format(to_define)
try:
# Use OwlBot API to fetch definition.
api_result = requests.get(DefineHandler.DEFINITION_API_URL.format(to_define_lower))
api_result = requests.get(self.DEFINITION_API_URL.format(to_define_lower))
# Convert API result from string to JSON format.
definitions = api_result.json()
# Could not fetch definitions for the given word.
if not definitions:
response += DefineHandler.REQUEST_ERROR_MESSAGE
else: # Definitions available.
response += self.REQUEST_ERROR_MESSAGE
else: # Definitions available.
# Show definitions line by line.
for d in definitions:
example = d['example'] if d['example'] else '*No example available.*'
response += '\n' + '* (**{}**) {}\n&nbsp;&nbsp;{}'.format(d['type'], d['defenition'], html2text.html2text(example))
except Exception as e:
response += DefineHandler.REQUEST_ERROR_MESSAGE
response += self.REQUEST_ERROR_MESSAGE
logging.exception(e)
return response
def handle_message(DefineHandler, message, client, state_handler):
original_content = message['content']
response = DefineHandler._handle_definition(original_content)
client.send_message(dict(
type='stream',
to=message['display_recipient'],
subject=message['sender_email'],
content=response
))
handler_class = DefineHandler

View File

@@ -12,10 +12,10 @@ is not in the dictionary, the definition is not displayed.
* For example, if the user says "@define crash", all the meanings of crash
appear, each in a separate line.
![Correct Word](correct_word.png)
![Correct Word](assets/correct_word.png)
* If the user enters a wrong word, like "@define cresh" or "@define crish",
then an error message saying no definition is available is displayed.
![Wrong Word](wrong_word.png)
![Wrong Word](assets/wrong_word.png)

View File

@@ -0,0 +1,28 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestDefineBot(BotTestCase):
bot_name = "define"
def test_bot(self):
expected = {
"": 'Please enter a word to define.',
"foo": "**foo**:\nDefinition not available.",
"cat": ("**cat**:\n\n* (**noun**) a small domesticated carnivorous mammal "
"with soft fur, a short snout, and retractile claws. It is widely "
"kept as a pet or for catching mice, and many breeds have been "
"developed.\n&nbsp;&nbsp;their pet cat\n\n"),
}
self.check_expected_responses(expected)

View File

View File

Before

Width:  |  Height:  |  Size: 287 KiB

After

Width:  |  Height:  |  Size: 287 KiB

View File

Before

Width:  |  Height:  |  Size: 180 KiB

After

Width:  |  Height:  |  Size: 180 KiB

View File

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 160 KiB

View File

Before

Width:  |  Height:  |  Size: 170 KiB

After

Width:  |  Height:  |  Size: 170 KiB

View File

@@ -18,36 +18,25 @@ def encrypt(text):
class EncryptHandler(object):
'''
This bot allows users to quickly encrypt messages using ROT13 encryption.
It encrypts/decrypts messages starting with @encrypt.
It encrypts/decrypts messages starting with @mention-bot.
'''
def usage(self):
return '''
This bot uses ROT13 encryption for its purposes.
It responds to me starting with @encrypt.
It responds to me starting with @mention-bot.
Feeding encrypted messages into the bot decrypts them.
'''
def triage_message(self, message, client):
original_content = message['content']
# This makes sure that the bot only replies to messages it supposed to reply to.
should_be_encrypted = original_content.startswith('@encrypt')
return should_be_encrypted
def handle_message(self, message, client, state_handler):
original_content = message['content']
temp_content = encrypt(original_content.replace('@encrypt', ''))
send_content = "Encrypted/Decrypted text: " + temp_content
bot_response = self.get_bot_encrypt_response(message)
client.send_reply(message, bot_response)
client.send_message(dict(
type='stream',
to=message['display_recipient'],
subject=message['subject'],
content = send_content
))
def get_bot_encrypt_response(self, message):
original_content = message['content']
temp_content = encrypt(original_content)
send_content = "Encrypted/Decrypted text: " + temp_content
return send_content
handler_class = EncryptHandler

View File

@@ -0,0 +1,27 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestEncryptBot(BotTestCase):
bot_name = "encrypt"
def test_bot(self):
expected = {
"": "Encrypted/Decrypted text: ",
"Let\'s Do It": "Encrypted/Decrypted text: Yrg\'f Qb Vg",
"me&mom together..!!": "Encrypted/Decrypted text: zr&zbz gbtrgure..!!",
"foo bar": "Encrypted/Decrypted text: sbb one",
"Please encrypt this": "Encrypted/Decrypted text: Cyrnfr rapelcg guvf",
}
self.check_expected_responses(expected)

View File

View File

@@ -4,7 +4,7 @@ class FollowupHandler(object):
'''
This plugin facilitates creating follow-up tasks when
you are using Zulip to conduct a virtual meeting. It
looks for messages starting with '@followup'.
looks for messages starting with '@mention-bot'.
In this example, we write follow up items to a special
Zulip stream called "followup," but this code could
@@ -16,36 +16,31 @@ class FollowupHandler(object):
return '''
This plugin will allow users to flag messages
as being follow-up items. Users should preface
messages with "@followup".
messages with "@mention-bot".
Before running this, make sure to create a stream
called "followup" that your API user can send to.
'''
def triage_message(self, message, client):
original_content = message['content']
# This next line of code is defensive, as we
# never want to get into an infinite loop of posting follow
# ups for own follow ups!
if message['display_recipient'] == 'followup':
return False
is_follow_up = (original_content.startswith('@followup') or
original_content.startswith('@follow-up'))
return is_follow_up
def handle_message(self, message, client, state_handler):
if message['content'] == '':
bot_response = "Please specify the message you want to send to followup stream after @mention-bot"
client.send_reply(message, bot_response)
else:
bot_response = self.get_bot_followup_response(message)
client.send_message(dict(
type='stream',
to='followup',
subject=message['sender_email'],
content=bot_response,
))
def get_bot_followup_response(self, message):
original_content = message['content']
original_sender = message['sender_email']
new_content = original_content.replace('@followup',
'from %s:' % (original_sender,))
temp_content = 'from %s: ' % (original_sender,)
new_content = temp_content + original_content
client.send_message(dict(
type='stream',
to='followup',
subject=message['sender_email'],
content=new_content,
))
return new_content
handler_class = FollowupHandler

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestFollowUpBot(BotTestCase):
bot_name = "followup"
def test_bot(self):
expected_send_reply = {
"": 'Please specify the message you want to send to followup stream after @mention-bot'
}
self.check_expected_responses(expected_send_reply, expected_method='send_reply')
expected_send_message = {
"foo": {
'type': 'stream',
'to': 'followup',
'subject': 'foo_sender@zulip.com',
'content': 'from foo_sender@zulip.com: foo',
},
"I have completed my task": {
'type': 'stream',
'to': 'followup',
'subject': 'foo_sender@zulip.com',
'content': 'from foo_sender@zulip.com: I have completed my task',
},
}
self.check_expected_responses(expected_send_message, expected_method='send_message')

View File

View File

@@ -9,13 +9,13 @@ from six.moves import configparser as cp
from six.moves import range
home = expanduser('~')
CONFIG_PATH = home + '/zulip/contrib_bots/bots/foursquare/FourSquareBot/settings.ini'
CONFIG_PATH = home + '/zulip/api/bots/foursquare/foursquare.config'
def get_api_key():
# settings.ini must have been moved from
# ~/zulip/contrib_bots/bots/foursquare/FourSquareBot/settings.ini into
# ~/settings.ini for program to work
# see doc.md for more information
# foursquare.config must have been moved from
# ~/zulip/api/bots/foursquare/foursquare.config into
# ~/foursquare.config for program to work
# see readme.md for more information
with open(CONFIG_PATH) as settings:
config = cp.ConfigParser()
config.readfp(settings)
@@ -30,13 +30,13 @@ class FoursquareHandler(object):
This plugin allows users to search for restaurants nearby an inputted
location to a limit of 3 venues for every location. The name, address
and description of the restaurant will be outputted.
It looks for messages starting with '@foursquare'.
It looks for messages starting with '@mention-bot'.
If you need help, simply type:
@foursquare /help into the Compose Message box
@mention-bot /help into the Compose Message box
Sample input:
@foursquare Chicago, IL
@foursquare help
@mention-bot Chicago, IL
@mention-bot help
'''
help_info = '''
@@ -45,18 +45,10 @@ cusine of a restaurant in that exact order.
Please note the required use of quotes in the search location.
Example Inputs:
@foursquare 'Millenium Park' 8000 donuts
@foursquare 'Melbourne, Australia' 40000 seafood
@mention-bot 'Millenium Park' 8000 donuts
@mention-bot 'Melbourne, Australia' 40000 seafood
'''
def triage_message(self, message, client):
callers = ['@FourSquare', '@Foursquare', '@foursquare', '@4square', '@4sq']
for call in callers:
if call in message['content']:
return True
break
return False
def format_json(self, venues):
def format_venue(venue):
name = venue['name']
@@ -68,19 +60,7 @@ Example Inputs:
return '\n'.join(format_venue(venue) for venue in venues)
def send_info(self, message, letter, client):
if message['type'] == 'private':
client.send_message(dict(
type='private',
to=message['sender_email'],
content=letter,
))
else:
client.send_message(dict(
type='stream',
subject=message['subject'],
to=message['display_recipient'],
content=letter,
))
client.send_reply(message, letter)
def handle_message(self, message, client, state_handler):
words = message['content'].split()
@@ -98,7 +78,7 @@ Example Inputs:
pass
# Optional params for HTTP request.
if len(words) >= 2:
if len(words) >= 1:
try:
params['radius'] = re.search('([0-9]){3,}', message['content']).group(0)
except AttributeError:
@@ -115,7 +95,7 @@ Example Inputs:
received_json = response.json()
else:
self.send_info(message,
"Invalid Request\nIf stuck, try '@foursquare help'.",
"Invalid Request\nIf stuck, try '@mention-bot help'.",
client)
return
@@ -127,7 +107,7 @@ Example Inputs:
return
self.send_info(message,
"Invalid Request\nIf stuck, try '@foursquare help'.",
"Invalid Request\nIf stuck, try '@mention-bot help'.",
client)
return

View File

@@ -28,5 +28,5 @@ Food nearby 'Chicago, IL' coming right up:
* If the user enters a wrong word, like "@foursquare 80000 donuts" or "@foursquare",
then an error message saying invalid input will be displayed.
* To get the required API Key, visit: https://developer.foursquare.com/overview/auth
* To get the required API key, visit: https://developer.foursquare.com/overview/auth
for more information.

View File

View File

@@ -22,45 +22,20 @@ class GiphyHandler(object):
'''
This plugin posts a GIF in response to the keywords provided by the user.
Images are provided by Giphy, through the public API.
The bot looks for messages starting with "@giphy" or @mention of the bot
The bot looks for messages starting with @mention of the bot
and responds with a message with the GIF based on provided keywords.
It also responds to private messages.
'''
def usage(self):
return '''
This plugin allows users to post GIFs provided by Giphy.
Users should preface keywords with "@giphy" or the Giphy-bot @mention.
Users should preface keywords with the Giphy-bot @mention.
The bot responds also to private messages.
'''
def triage_message(self, message, client):
# To prevent infinite loop in private message, bot will detect
# if the sender name is the bot name it will return false.
if message['type'] == 'private':
return client.full_name != message['sender_full_name']
original_content = message['content']
is_giphy_called = (original_content.startswith('@giphy ') or
message['is_mentioned'])
return is_giphy_called
def handle_message(self, message, client, state_handler):
bot_response = get_bot_giphy_response(message, client)
if message['type'] == 'private':
client.send_message(dict(
type='private',
to=message['sender_email'],
content=bot_response,
))
else:
client.send_message(dict(
type='stream',
to=message['display_recipient'],
subject=message['subject'],
content=bot_response,
))
client.send_reply(message, bot_response)
class GiphyNoResultException(Exception):
@@ -99,23 +74,9 @@ def get_url_gif_giphy(keyword, api_key):
def get_bot_giphy_response(message, client):
# Handle the message that called through mention.
if message['is_mentioned']:
bot_mention = r'^@(\*\*{0}\*\*\s|{0}\s)(?=.*)'.format(client.full_name)
start_with_mention = re.compile(bot_mention).match(message['content'])
if start_with_mention:
keyword = message['content'][len(start_with_mention.group()):]
else:
return 'Please mention me first, then type the keyword.'
# Handle the message that called through the specified keyword.
elif message['content'].startswith('@giphy '):
keyword = message['content'][len('@giphy '):]
# Handle the private message.
elif message['type'] == 'private':
keyword = message['content']
# Each exception has a specific reply should "gif_url" return a number.
# The bot will post the appropriate message for the error.
keyword = message['content']
try:
gif_url = get_url_gif_giphy(keyword, get_giphy_api_key_from_config())
except requests.exceptions.ConnectionError:

View File

@@ -0,0 +1,61 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import json
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
from bots.giphy import giphy
def get_http_response_json(gif_url):
response_json = {
'meta': {
'status': 200
},
'data': {
'images': {
'original': {
'url': gif_url
}
}
}
}
return response_json
def get_bot_response(gif_url):
return ('[Click to enlarge](%s)'
'[](/static/images/interactive-bot/giphy/powered-by-giphy.png)'
% (gif_url))
def get_http_request(keyword):
return {
'api_url': giphy.GIPHY_TRANSLATE_API,
'params': {
's': keyword,
'api_key': giphy.get_giphy_api_key_from_config()
}
}
class TestGiphyBot(BotTestCase):
bot_name = "giphy"
def test_bot(self):
# This message calls `send_reply` function of BotHandlerApi
keyword = "Hello"
gif_url = "https://media4.giphy.com/media/3o6ZtpxSZbQRRnwCKQ/giphy.gif"
expectations = {
keyword: get_bot_response(gif_url)
}
self.check_expected_responses(
expectations=expectations,
http_request=get_http_request(keyword),
http_response=get_http_response_json(gif_url)
)

View File

View File

@@ -1,4 +1,4 @@
# See readme-github-comment-bot.md for instructions on running this code.
# See readme.md for instructions on running this code.
from __future__ import absolute_import
from __future__ import print_function
from . import github
@@ -15,13 +15,13 @@ class InputError(IndexError):
class GitHubHandler(object):
'''
This plugin allows you to comment on a GitHub issue, under a certain repository.
It looks for messages starting with '@comment' or '@gcomment'.
It looks for messages starting with '@mention-bot'.
'''
def usage(self):
return '''
This bot will allow users to comment on a GitHub issue.
Users should preface messages with '@comment' or '@gcomment'.
Users should preface messages with '@mention-bot'.
You will need to have a GitHub account.
Before running this, make sure to get a GitHub OAuth token.
@@ -39,25 +39,11 @@ class GitHubHandler(object):
'<repository_owner>/<repository>/<issue_number>/<your_comment>'.
'''
def triage_message(self, message, client):
original_content = message['content']
is_comment = (original_content.startswith('@comment') or
original_content.startswith('@gcomment'))
return is_comment
def handle_message(self, message, client, state_handler):
original_content = message['content']
original_sender = message['sender_email']
# this handles the message if its starts with @comment
if original_content.startswith('@comment'):
handle_input(client, original_content, original_sender)
# handle if message starts with @gcomment
elif original_content.startswith('@gcomment'):
handle_input(client, original_content, original_sender)
handle_input(client, original_content, original_sender)
handler_class = GitHubHandler

View File

@@ -26,8 +26,8 @@ github_token = <oauth_token> (The personal access token for the GitHub bot)
Here is an example of running the `git_hub_comment` bot from
inside a Zulip repo:
`cd ~/zulip/contrib_bots`
`./run.py bots/git_hub_comment/git_hub_comment.py --config-file ~/.zuliprc-prod`
`cd ~/zulip/api`
`bots_api/run.py bots/git_hub_comment/git_hub_comment.py --config-file ~/.zuliprc-prod`
Once the bot code starts running, you will see a
message explaining how to use the bot, as well as

View File

View File

View File

@@ -13,7 +13,7 @@ import urllib.request
class IssueHandler(object):
'''
This plugin facilitates sending issues to github, when
an item is prefixed with '@issue' or '@bug'
an item is prefixed with '@mention-bot'.
It will also write items to the issues stream, as well
as reporting it to github
@@ -30,7 +30,7 @@ class IssueHandler(object):
def usage(self):
return '''
This plugin will allow users to flag messages
as being issues with Zulip by using te prefix '@issue'
as being issues with Zulip by using te prefix '@mention-bot'.
Before running this, make sure to create a stream
called "issues" that your API user can send to.
@@ -47,30 +47,20 @@ class IssueHandler(object):
github_token = <oauth_token> (The personal access token for the GitHub bot)
'''
def triage_message(self, message, client):
original_content = message['content']
# This next line of code is defensive, as we
# never want to get into an infinite loop of posting follow
# ups for own follow ups!
if message['display_recipient'] == 'issue':
return False
is_issue = original_content.startswith('@issue')
return is_issue
def handle_message(self, message, client, state_handler):
original_content = message['content']
original_sender = message['sender_email']
new_content = original_content.replace('@issue', 'by {}:'.format(original_sender,))
temp_content = 'by {}:'.format(original_sender,)
new_content = temp_content + original_content
# gets the repo url
url_new = self.URL.format(self.REPO_OWNER, self.REPO_NAME)
# signs into github using the provided username and password
session = github.auth()
# Gets rid of the @issue in the issue title
issue_title = message['content'].replace('@issue', '').strip()
issue_title = message['content'].strip()
issue_content = ''
new_issue_title = ''
for part_of_title in issue_title.split():

View File

View File

@@ -0,0 +1,93 @@
# See readme.md for instructions on running this code.
from __future__ import print_function
import logging
import http.client
from six.moves.urllib.request import urlopen
# Uses the Google search engine bindings
# pip install --upgrade google
from google import search
def get_google_result(search_keywords):
help_message = "To use this bot, start messages with @mentioned-bot, \
followed by what you want to search for. If \
found, Zulip will return the first search result \
on Google.\
\
An example message that could be sent is:\
'@mentioned-bot zulip' or \
'@mentioned-bot how to create a chatbot'."
if search_keywords == 'help':
return help_message
elif search_keywords == '' or search_keywords is None:
return help_message
else:
try:
urls = search(search_keywords, stop=20)
urlopen('http://216.58.192.142', timeout=1)
except http.client.RemoteDisconnected as er:
logging.exception(er)
return 'Error: No internet connection. {}.'.format(er)
except Exception as e:
logging.exception(e)
return 'Error: Search failed. {}.'.format(e)
try:
url = next(urls)
except AttributeError as a_err:
# google.search query failed and urls is of object
# 'NoneType'
logging.exception(a_err)
return "Error: Google search failed with a NoneType result. {}.".format(a_err)
except TypeError as t_err:
# google.search query failed and returned None
# This technically should not happen but the prior
# error check assumed this behavior
logging.exception(t_err)
return "Error: Google search function failed. {}.".format(t_err)
except Exception as e:
logging.exception(e)
return 'Error: Search failed. {}.'.format(e)
return 'Success: {}'.format(url)
class GoogleSearchHandler(object):
'''
This plugin allows users to enter a search
term in Zulip and get the top URL sent back
to the context (stream or private) in which
it was called. It looks for messages starting
with @mentioned-bot.
'''
def usage(self):
return '''
This plugin will allow users to search
for a given search term on Google from
Zulip. Use '@mentioned-bot help' to get
more information on the bot usage. Users
should preface messages with
@mentioned-bot.
'''
def handle_message(self, message, client, state_handler):
original_content = message['content']
result = get_google_result(original_content)
client.send_reply(message, result)
handler_class = GoogleSearchHandler
def test():
try:
urlopen('http://216.58.192.142', timeout=1)
print('Success')
return True
except http.client.RemoteDisconnected as e:
print('Error: {}'.format(e))
return False
if __name__ == '__main__':
test()

View File

@@ -0,0 +1,23 @@
# Google Search bot
This bot allows users to do Google search queries and have the bot
respond with the first search result. It is by default set to the
highest safe-search setting.
## Usage
Run this bot as described
[here](http://zulip.readthedocs.io/en/latest/bots-guide.html#how-to-deploy-a-bot).
Use this bot with the following command
`@mentioned-bot <search terms>`
This will return the first link found by Google for `<search terms>`
and print the resulting URL.
If no `<search terms>` are entered, a help message is printed instead.
If there was an error in the process of running the search (socket
errors, Google search function failed, or general failures), an error
message is returned.

View File

View File

@@ -0,0 +1,18 @@
# See readme.md for instructions on running this code.
class HelloWorldHandler(object):
def usage(self):
return '''
This is a boilerplate bot that responds to a user query with
"beep boop", which is robot for "Hello World".
This bot can be used as a template for other, more
sophisticated, bots.
'''
def handle_message(self, message, client, state_handler):
content = 'beep boop'
client.send_reply(message, content)
handler_class = HelloWorldHandler

View File

@@ -0,0 +1,4 @@
Simple Zulip bot that will respond to any query with a "beep boop".
The helloworld bot is a boilerplate bot that can be used as a
template for more sophisticated/evolved Zulip bots.

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
from six.moves import zip
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestHelloWorldBot(BotTestCase):
bot_name = "helloworld"
def test_bot(self):
txt = "beep boop"
messages = ["", "foo", "Hi, my name is abc"]
self.check_expected_responses(dict(list(zip(messages, len(messages)*[txt]))))

View File

18
api/bots/help/help.py Normal file
View File

@@ -0,0 +1,18 @@
# See readme.md for instructions on running this code.
class HelpHandler(object):
def usage(self):
return '''
This plugin will give info about Zulip to
any user that types a message saying "help".
This is example code; ideally, you would flesh
this out for more useful help pertaining to
your Zulip instance.
'''
def handle_message(self, message, client, state_handler):
help_content = "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip"
client.send_reply(message, help_content)
handler_class = HelpHandler

View File

@@ -0,0 +1,23 @@
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import print_function
import os
import sys
from six.moves import zip
our_dir = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.normpath(os.path.join(our_dir)))
# For dev setups, we can find the API in the repo itself.
if os.path.exists(os.path.join(our_dir, '..')):
sys.path.insert(0, '..')
from bots_test_lib import BotTestCase
class TestHelpBot(BotTestCase):
bot_name = "help"
def test_bot(self):
txt = "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip"
messages = ["", "help", "Hi, my name is abc"]
self.check_expected_responses(dict(list(zip(messages, len(messages)*[txt]))))

View File

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 9.0 KiB

View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@@ -12,6 +12,8 @@ Note:
required by `howdoi`.
"""
from __future__ import absolute_import
import sys
import logging
from textwrap import fill
@@ -30,16 +32,16 @@ class HowdoiHandler(object):
in your questions.
There are two possible commands:
* @howdowe > This would return the answer to the same
* @mention-bot howdowe > This would return the answer to the same
stream that it was called from.
* @howdoi > The bot would send a private message to the
* @mention-bot howdoi > The bot would send a private message to the
user containing the answer.
By default, howdoi only returns the coding section of the
first search result if possible, to see the full answer
from Stack Overflow, append a '!' to the commands.
(ie '@howdoi!', '@howdowe!')
(ie '@mention-bot howdoi!', '@mention-bot howdowe!')
'''
MAX_LINE_LENGTH = 85
@@ -50,26 +52,12 @@ class HowdoiHandler(object):
answers from Stackoverflow. Users should preface
their questions with one of the following:
* @howdowe > Answer to the same stream
* @howdoi > Answer via private message
* @mention-bot howdowe > Answer to the same stream
* @mention-bot howdoi > Answer via private message
* @howdowe! OR @howdoi! > Full answer from SO
* @mention-bot howdowe! OR @mention-bot howdoi! > Full answer from SO
'''
def triage_message(self, message, client):
cmd_list = ['@howdowe', '@howdoi', '@howdowe!', '@howdoi!']
question = message['content']
# This next line of code is defensive, as we never want
# to get into an infinite loop of searching answers
# from Stackoverflow!
if message['sender_email'].startswith('howdoi'):
return False
is_howdoi = any([question.startswith(cmd) for cmd in cmd_list])
return is_howdoi
def line_wrap(self, string, length):
lines = string.split("\n")
@@ -94,36 +82,36 @@ class HowdoiHandler(object):
return answer
def handle_message(self, message, client, state_handler):
question = message['content']
question = message['content'].strip()
if question.startswith('@howdowe!'):
if question.startswith('howdowe!'):
client.send_message(dict(
type='stream',
to=message['display_recipient'],
subject=message['subject'],
content=self.get_answer('@howdowe!', question)
content=self.get_answer('howdowe!', question)
))
elif question.startswith('@howdoi!'):
elif question.startswith('howdoi!'):
client.send_message(dict(
type='private',
to=message['sender_email'],
content=self.get_answer('@howdoi!', question)
content=self.get_answer('howdoi!', question)
))
elif question.startswith('@howdowe'):
elif question.startswith('howdowe'):
client.send_message(dict(
type='stream',
to=message['display_recipient'],
subject=message['subject'],
content=self.get_answer('@howdowe', question)
content=self.get_answer('howdowe', question)
))
elif question.startswith('@howdoi'):
elif question.startswith('howdoi'):
client.send_message(dict(
type='private',
to=message['sender_email'],
content=self.get_answer('@howdoi', question)
content=self.get_answer('howdoi', question)
))

View File

@@ -23,24 +23,24 @@ answer will be formatted differently depending the chosen command.
Question -> `@howdowe use supervisor in elixir`
![howdowe question](question_howdowe.png)
![howdowe question](assets/question_howdowe.png)
Answer -> Howdoi would try to **only** respond with the coding section
of the answer.
![howdowe answer](answer_howdowe.png)
![howdowe answer](assets/answer_howdowe.png)
#### Example 2
Question -> `@howdoi! stack vs heap`
![howdoi! question](question_howdoi_all.png)
![howdoi! question](assets/question_howdoi_all.png)
Answer -> Howdoi would return the **full** stackoverflow answer via
**private message** to the original sender. The URL of the answer can be
seen at the bottom of the message.
![howdoi! answer](answer_howdoi_all.png)
![howdoi! answer](assets/answer_howdoi_all.png)
**Note:**

View File

View File

@@ -0,0 +1,30 @@
# See readme.md for instructions on running this code.
class IncrementorHandler(object):
def __init__(self):
self.number = 0
self.message_id = None
def usage(self):
return '''
This is a boilerplate bot that makes use of the
update_message function. For the first @-mention, it initially
replies with one message containing a `1`. Every time the bot
is @-mentioned, this number will be incremented in the same message.
'''
def handle_message(self, message, client, state_handler):
self.number += 1
if self.message_id is None:
result = client.send_reply(message, str(self.number))
self.message_id = result['id']
else:
client.update_message(dict(
message_id=self.message_id,
content=str(self.number),
))
handler_class = IncrementorHandler

View File

@@ -0,0 +1,6 @@
# Incrementor bot
This is a boilerplate bot that makes use of the
update_message function. For the first @-mention, it initially
replies with one message containing a `1`. Every time the bot
is @-mentioned, this number will be incremented in the same message.

View File

View File

Before

Width:  |  Height:  |  Size: 83 KiB

After

Width:  |  Height:  |  Size: 83 KiB

View File

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 49 KiB

View File

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@@ -11,14 +11,14 @@ except ImportError:
raise ImportError("""It looks like you are missing chatterbot.
Please: pip install chatterbot""")
CONTRIB_BOTS_DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(os.path.dirname(CONTRIB_BOTS_DIR))
sys.path.insert(0, os.path.dirname(CONTRIB_BOTS_DIR))
BOTS_DIR = os.path.dirname(os.path.abspath(__file__))
os.chdir(os.path.dirname(BOTS_DIR))
sys.path.insert(0, os.path.dirname(BOTS_DIR))
JOKES_PATH = os.path.join(CONTRIB_BOTS_DIR, 'John/var/jokes.json')
DATABASE_PATH = os.path.join(CONTRIB_BOTS_DIR, 'John/var/database.db')
DIRECTORY_PATH = os.path.join(CONTRIB_BOTS_DIR, 'John')
VAR_PATH = os.path.join(CONTRIB_BOTS_DIR, 'John/var')
JOKES_PATH = os.path.join(BOTS_DIR, 'assets/var/jokes.json')
DATABASE_PATH = os.path.join(BOTS_DIR, 'assets/var/database.db')
DIRECTORY_PATH = os.path.join(BOTS_DIR, 'assets')
VAR_PATH = os.path.join(BOTS_DIR, 'assets/var')
if not os.path.exists(DIRECTORY_PATH):
os.makedirs(DIRECTORY_PATH)
@@ -38,7 +38,7 @@ def create_chat_bot(no_learn):
"response_selection_method": "chatterbot.response_selection.get_random_response",
"statement_comparison_function": "chatterbot.comparisons.levenshtein_distance"
}],
output_adapter="chatterbot.output.OutputFormatAdapter",
output_adapter="chatterbot.output.OutputAdapter",
output_format='text',
database=DATABASE_PATH,
silence_performance_warning="True",
@@ -109,22 +109,15 @@ class JohnHandler(object):
def usage(self):
return '''
Before running this, make sure to create a stream
called "VirtualHelp" that your API user can send to.
This bot aims to be Zulip's virtual assistant. It
finds the best match from a certain input.
Also understands the English language and can
mantain a conversation, joke and give useful information.
'''
def triage_message(self, message, client):
original_content = message['content'].lower()
return (original_content.startswith("@john") or
original_content.startswith("@**john**"))
def handle_message(self, message, client, state_handler):
original_content = message['content']
client.send_message(dict(
type='stream',
to='VirtualHelp',
subject="John",
content=bota.get_response(original_content)
))
bot_response = str(bota.get_response(original_content))
client.send_reply(message, bot_response)
handler_class = JohnHandler

View File

@@ -10,7 +10,7 @@ interactive bot that uses machine learning heuristics to simulate a
conversation with the user. He has a great sense of humor and
is also powered by Open Source code!
![Joke John](joke.png)
![Joke John](assets/joke.png)
How it works?
John is initially trained with Corpus files, or large text files.
@@ -20,11 +20,11 @@ try to find the response that best matches the input according to the Levenshtei
which is a string metric for measuring the difference between two sequences. If several
responses have the same acurracy, he will choose one at random.
![Meet John](greetings.png)
![Meet John](assets/greetings.png)
Can he learn by himself?
John's engine allows him to learn from his conversations with people. However,
without strict supervision bots that learn from people can do harm, so learning
is currently restricted to his initial corpus.
![Assist](assist.png)
![Assist](assets/assist.png)

View File

@@ -29,8 +29,8 @@ to messages in any of the following settings:
Here is an example of running the "follow-up" bot from
inside a Zulip repo (and in your remote instance):
cd ~/zulip/contrib_bots
./run.py bots/followup/followup.py --config-file ~/.zuliprc-prod
cd ~/zulip/api
bots_api/run.py bots/followup/followup.py --config-file ~/.zuliprc-prod
Once the bot code starts running, you will see a
message explaining how to use the bot, as well as
@@ -101,8 +101,8 @@ document you are reading now).
Each bot library simply needs to do the following:
- Define a class that supports the methods `usage`,
`triage_message`, and `handle_message`.
- Define a class that supports the methods `usage`
and `handle_message`.
- Set `handler_class` to be the name of that class.
(We make this a two-step process to reduce code repetition

View File

Some files were not shown because too many files have changed in this diff Show More