forked from pool/python-plotly
Compare commits
8 Commits
Author | SHA256 | Date | |
---|---|---|---|
67ee2fca1d | |||
4392f238d9 | |||
3aa8c0dd72 | |||
4ce746a58c | |||
2e001986b4 | |||
1a2d99f41a | |||
e8f2a2e71a | |||
b22a92f46d |
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d1e422b2ad02684fa290f5f2c28e571387d9b1c1e135b1a6a63539aab13efb07
|
||||
size 58173524
|
||||
oid sha256:4351fbb16baa842ae6ec45db8d1d99a2fb7058613ed4960ee6315f5fee24f86f
|
||||
size 150322872
|
||||
|
File diff suppressed because it is too large
Load Diff
11872
package-lock.json
generated
11872
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,91 +0,0 @@
|
||||
From 0199582127111c453db70a0133db8c64baca7c40 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Greiner <code@bnavigator.de>
|
||||
Date: Sun, 2 Jun 2024 16:43:06 +0200
|
||||
Subject: [PATCH 1/3] Remove np.nan and np.inf aliases no longer present in
|
||||
numpy2
|
||||
|
||||
---
|
||||
.../tests/test_optional/test_utils/test_utils.py | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py b/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py
|
||||
index cf32e1bdf..d7d982e63 100644
|
||||
--- a/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py
|
||||
+++ b/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py
|
||||
@@ -34,7 +34,7 @@ if matplotlylib:
|
||||
|
||||
## JSON encoding
|
||||
numeric_list = [1, 2, 3]
|
||||
-np_list = np.array([1, 2, 3, np.NaN, np.NAN, np.Inf, dt(2014, 1, 5)])
|
||||
+np_list = np.array([1, 2, 3, np.nan, np.inf, dt(2014, 1, 5)])
|
||||
mixed_list = [
|
||||
1,
|
||||
"A",
|
||||
@@ -45,7 +45,7 @@ mixed_list = [
|
||||
dt_list = [dt(2014, 1, 5), dt(2014, 1, 5, 1, 1, 1), dt(2014, 1, 5, 1, 1, 1, 1)]
|
||||
|
||||
df = pd.DataFrame(
|
||||
- columns=["col 1"], data=[1, 2, 3, dt(2014, 1, 5), pd.NaT, np.NaN, np.Inf]
|
||||
+ columns=["col 1"], data=[1, 2, 3, dt(2014, 1, 5), pd.NaT, np.nan, np.inf]
|
||||
)
|
||||
|
||||
rng = pd.date_range("1/1/2011", periods=2, freq="H")
|
||||
@@ -184,7 +184,7 @@ class TestJSONEncoder(TestCase):
|
||||
|
||||
assert (
|
||||
js1 == '{"type": "scatter3d", "x": [1, 2, 3], '
|
||||
- '"y": [1, 2, 3, null, null, null, "2014-01-05T00:00:00"], '
|
||||
+ '"y": [1, 2, 3, null, null, "2014-01-05T00:00:00"], '
|
||||
'"z": [1, "A", "2014-01-05T00:00:00", '
|
||||
'"2014-01-05T01:01:01", "2014-01-05T01:01:01.000001"]}'
|
||||
)
|
||||
@@ -195,9 +195,9 @@ class TestJSONEncoder(TestCase):
|
||||
_json.dumps(figure, cls=utils.PlotlyJSONEncoder, sort_keys=True)
|
||||
|
||||
# Test data wasn't mutated
|
||||
- np_array = np.array([1, 2, 3, np.NaN, np.NAN, np.Inf, dt(2014, 1, 5)])
|
||||
+ np_array = np.array([1, 2, 3, np.nan, np.inf, dt(2014, 1, 5)])
|
||||
for k in range(len(np_array)):
|
||||
- if k in [3, 4]:
|
||||
+ if k == 3:
|
||||
# check NaN
|
||||
assert np.isnan(np_list[k]) and np.isnan(np_array[k])
|
||||
else:
|
||||
@@ -237,7 +237,7 @@ class TestJSONEncoder(TestCase):
|
||||
# Test that data wasn't mutated
|
||||
assert_series_equal(
|
||||
df["col 1"],
|
||||
- pd.Series([1, 2, 3, dt(2014, 1, 5), pd.NaT, np.NaN, np.Inf], name="col 1"),
|
||||
+ pd.Series([1, 2, 3, dt(2014, 1, 5), pd.NaT, np.nan, np.inf], name="col 1"),
|
||||
)
|
||||
|
||||
j2 = _json.dumps(df.index, cls=utils.PlotlyJSONEncoder)
|
||||
--
|
||||
2.45.1
|
||||
|
||||
From f88554113e8cf55a1d756c3f0d33b92a891d0475 Mon Sep 17 00:00:00 2001
|
||||
From: Ben Greiner <code@bnavigator.de>
|
||||
Date: Sun, 2 Jun 2024 16:48:34 +0200
|
||||
Subject: [PATCH 2/3] Avoid putting 255 into int8 due to new numpy 2 type
|
||||
promotion rules
|
||||
|
||||
---
|
||||
.../plotly/plotly/tests/test_optional/test_px/test_imshow.py | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/packages/python/plotly/plotly/tests/test_optional/test_px/test_imshow.py b/packages/python/plotly/plotly/tests/test_optional/test_px/test_imshow.py
|
||||
index c2e863c84..d8f9ad98c 100644
|
||||
--- a/packages/python/plotly/plotly/tests/test_optional/test_px/test_imshow.py
|
||||
+++ b/packages/python/plotly/plotly/tests/test_optional/test_px/test_imshow.py
|
||||
@@ -341,7 +341,7 @@ def test_imshow_source_dtype_zmax(dtype, contrast_rescaling):
|
||||
assert (
|
||||
np.abs(
|
||||
np.max(decode_image_string(fig.data[0].source))
|
||||
- - 255 * img.max() / np.iinfo(dtype).max
|
||||
+ - np.int64(255) * img.max() / np.iinfo(dtype).max
|
||||
)
|
||||
< 1
|
||||
)
|
||||
--
|
||||
2.45.1
|
||||
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:54c4f90f862e50f3e51259c2edd78872de2244e0a3e5ce465fed5204c22da83a
|
||||
size 31113116
|
3
plotly.py-6.1.2-gh.tar.gz
Normal file
3
plotly.py-6.1.2-gh.tar.gz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ea36c0da90c5ff4b041d50db9b32d64e8b8b670fe0f87dc7606129becf358d42
|
||||
size 10193925
|
@ -1,3 +1,153 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jun 19 11:15:21 UTC 2025 - Daniel Garcia <daniel.garcia@suse.com>
|
||||
|
||||
- Drop upstream patch plotly-pr4622-np2.patch
|
||||
- Remove jupyter sub-package, not part of the package anymore after
|
||||
the switch to anywidget gh#plotly/plotly.py#4823
|
||||
- Remove notebook from jupyter package, as part of jupyter notebook 6
|
||||
drop, gh#plotly/plotly.py#4822
|
||||
- Update to 6.1.2 (CVE-2025-5889, bsc#1244347)
|
||||
* Fix type checking and code highlighting for graph_objects classes [#5199]
|
||||
- Release 6.1.1
|
||||
* Prevent swallowing of ValueError when creating a figure with
|
||||
subplots [#3888]
|
||||
* Fix issue causing fig.write_image() to not generate an image
|
||||
[#5193]
|
||||
- Release 6.1.0
|
||||
## Updated
|
||||
* Add support for Kaleido>=v1.0.0 for image generation [#5062, #5177]
|
||||
* Reduce package bundle size by 18-24% via changes to code
|
||||
generation [#4978]
|
||||
## Fixed
|
||||
* Fix third-party widget display issues in v6 [#5102]
|
||||
* Add handling for case where jupyterlab or notebook is not
|
||||
installed [#5104]
|
||||
* Fix issue causing Plotly.js script to be embedded multiple times
|
||||
in Jupyter notebooks [#5112]
|
||||
* Re-add MIME renderer JupyterLab extension with JupyterLab 4
|
||||
support to reduce file sizes for offline notebooks [#5096]
|
||||
* Fix issue preventing plots from rendering in HTML notebook export
|
||||
when using 'vscode+notebook' renderer [#5154]
|
||||
- Release 6.0.1
|
||||
## Updated
|
||||
* Updated Plotly.js from version 3.0.0 to version 3.0.1. See the
|
||||
plotly.js CHANGELOG for more information.
|
||||
## Fixed
|
||||
* Fix TypeError when using orjson to serialize pandas.NA [#5040].
|
||||
* Fix issue where using category_orders on px.pie raised
|
||||
ColumnNotFoundError [#5000].
|
||||
* Fix incorrect DeprecationWarning shown when creating a px chart
|
||||
[#5080, #5086]
|
||||
- Release 6.0.0
|
||||
## Added
|
||||
* Add plotly[express] extra for easily installing Plotly Express
|
||||
dependencies [#4644]
|
||||
* Add subtitle attribute to all Plotly Express traces [#4830].
|
||||
## Removed
|
||||
* Drop deprecated pointcloud and heatmapgl traces from the API [#4815]
|
||||
* Drop tenacity dependency [#4831]
|
||||
* Drop support for Jupyter Notebook version 6 and earlier [#4822].
|
||||
The minimum supported version is now 7.0.0.
|
||||
## Updated
|
||||
* Update Plotly.js from version 2.34.2 to version 3.0.0 See the
|
||||
plotly.js CHANGELOG for more information. These changes are
|
||||
reflected in the auto-generated plotly.graph_objects module.
|
||||
Notable changes include:
|
||||
- Make offsetgroup work with barmode "stacked" and "relative" for
|
||||
bar traces [#7009]
|
||||
- Drop support for deprecated attributes titlefont, titleposition,
|
||||
titleside, and titleoffset [#7212].
|
||||
- Drop deprecated pointcloud and heatmapgl traces and gl2d
|
||||
subplots [#7213]
|
||||
- Drop support for deprecated bardir attribute (use orientation
|
||||
instead) [#7214]
|
||||
- Drop support for deprecated annotation.ref attribute (use
|
||||
annotation.xref and annotation.yref instead) [#7215]
|
||||
- Drop support for deprecated error bar opacity attribute (use
|
||||
alpha channel of error bar color attribute instead) [#7214]
|
||||
- Drop support for deprecated attribute gl3d.cameraposition (use
|
||||
gl3d.camera instead) [#7217]
|
||||
- Drop deprecated plot3dPixelRatio from config [#7231]
|
||||
- Drop deprecated zauto, zmin and zmax from the surface trace [#7234]
|
||||
- Drop deprecated autotick attributes from cartesian axes [#7236]
|
||||
- Drop transforms from the API [#7240, #7254]
|
||||
* Deprecate Mapbox-based traces.[#4900]. See the MapLibre Migration
|
||||
page for details on migrating from Mapbox to Maplibre.
|
||||
* Update plotly.py to use base64 encoding of typed arrays e.g. numpy
|
||||
in plotly JSON to keep precision intact and improve performance [#4470].
|
||||
* Make plotly-express dataframe agnostic via Narwhals [#4790].
|
||||
* Update go.FigureWidget to use anywidget [#4823]
|
||||
* Use modern native ES6 import to load plotly.js bundle instead of
|
||||
requirejs which is no longer under active development [#4736]
|
||||
## Fixed
|
||||
* Fix a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that caused
|
||||
LaTeX to not render in plotly charts [#4763].
|
||||
* Fix go.FigureWidget.show to return FigureWidget instead of
|
||||
displaying Figure [#4869]
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Dec 6 21:47:19 UTC 2024 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
- Skip scikit-image tests on python313: not available yet
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Wed Nov 27 12:02:14 UTC 2024 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
- Update to 5.24.1
|
||||
* Updated Plotly.js from version 2.35.0 to version 3.0.0-rc.0.
|
||||
See the plotly.js CHANGELOG for more information.
|
||||
- Release 5.24.0
|
||||
## Added
|
||||
* New px functions for maps: scatter_map, line_map,
|
||||
choropleth_map, and density_map.
|
||||
## Updated
|
||||
* Updated Plotly.js from version 2.34.0 to version 2.35.0. See
|
||||
the plotly.js CHANGELOG for more information. These changes are
|
||||
reflected in the auto-generated plotly.graph_objects module.
|
||||
Notable changes include:
|
||||
- Add new traces: scattermap, choroplethmap and densitymap and
|
||||
map subplots which use maplibre to render maps [#7015, #7060,
|
||||
#7085, #7088, #7090, #7092, #7094, #7134]
|
||||
- Deprecate mapbox traces and mapbox subplot [#7087]
|
||||
* Fixed a bug in integer validation of arrays that threw an error
|
||||
when an array contained a mix of strings and integers.
|
||||
* Fixed a bug in JupyterLab >= 4 and Jupyter Notebook >= 7 that
|
||||
caused latex to not render in plotly charts.
|
||||
* Use modern native ES6 import to load plotly.js bundle instead
|
||||
of requirejs which is no longer under active development
|
||||
- Release 5.23.0
|
||||
## Updated
|
||||
* Updated Plotly.js from version 2.32.0 to version 2.34.0. See
|
||||
the plotly.js CHANGELOG for more information. These changes
|
||||
are reflected in the auto-generated plotly.graph_objects
|
||||
module. Notable changes include:
|
||||
- Add subtitle attribute to layout.title to enable adding
|
||||
subtitles to plots [#7012]
|
||||
- Introduce "u" and "s" pseudo html tags to add partial
|
||||
underline and strike-through styles to SVG text elements
|
||||
[#7043]
|
||||
- Add geometric mean functionality and 'geometric mean
|
||||
ascending' + 'geometric mean descending' to category_order on
|
||||
cartesian axes [#6223], with thanks to @acxz and @prabhathc
|
||||
for the contribution!
|
||||
- Add axis property ticklabelindex for drawing the label for
|
||||
each minor tick n positions away from a major tick, with
|
||||
thanks to @my-tien for the contribution! [#7036]
|
||||
- Add property ticklabelstandoff and ticklabelshift to
|
||||
cartesian axes to adjust positioning of tick labels, with
|
||||
thanks to @my-tien for the contribution! [#7006]
|
||||
- Add x0shift, x1shift, y0shift, y1shift to shapes to add
|
||||
control over positioning of shape vertices on
|
||||
(multi-)category axes, with thanks to @my-tien for the
|
||||
contribution! [#7005]
|
||||
* Specify Python version 3.8-3.11 for development virtual
|
||||
environments and pin pytest at version 8.1.1 to match.
|
||||
* Update IntegerValidator to handle extras option to allow
|
||||
supporting additional keyword values. For example, 'bold' and
|
||||
'normal' as well as integers as used in font weights [#4612].
|
||||
- Refresh plotly-pr4622-np2.patch gh#plotly/plotly.py#4622
|
||||
- Do not depend on jupyter metapackge for tests
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jul 18 08:19:01 UTC 2024 - Ben Greiner <code@bnavigator.de>
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package python-plotly
|
||||
#
|
||||
# Copyright (c) 2024 SUSE LLC
|
||||
# Copyright (c) 2025 SUSE LLC
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@ -16,8 +16,9 @@
|
||||
#
|
||||
|
||||
|
||||
%bcond_without libalternatives
|
||||
Name: python-plotly
|
||||
Version: 5.22.0
|
||||
Version: 6.1.2
|
||||
Release: 0
|
||||
Summary: Library for collaborative, interactive, publication-quality graphs
|
||||
License: MIT
|
||||
@ -31,22 +32,20 @@ Source10: package-lock.json
|
||||
Source11: node_modules.spec.inc
|
||||
%include %{_sourcedir}/node_modules.spec.inc
|
||||
Source100: python-plotly-rpmlintrc
|
||||
# PATCH-FIX-UPSTREAM plotly-pr4622-np2.patch gh#plotly/plotly.py#4622
|
||||
Patch0: plotly-pr4622-np2.patch
|
||||
BuildRequires: %{python_module base >= 3.6}
|
||||
BuildRequires: %{python_module jupyterlab >= 3}
|
||||
BuildRequires: %{python_module notebook >= 5.3}
|
||||
BuildRequires: %{python_module packaging}
|
||||
BuildRequires: %{python_module pip}
|
||||
BuildRequires: %{python_module setuptools}
|
||||
BuildRequires: %{python_module tenacity >= 6.2.0}
|
||||
BuildRequires: %{python_module wheel}
|
||||
BuildRequires: alts
|
||||
BuildRequires: fdupes
|
||||
BuildRequires: jupyter-rpm-macros
|
||||
BuildRequires: local-npm-registry
|
||||
BuildRequires: python-rpm-macros
|
||||
Requires: alts
|
||||
Requires: python-narwhals
|
||||
Requires: python-packaging
|
||||
Requires: python-tenacity >= 6.2.0
|
||||
Recommends: python-ipython
|
||||
Recommends: python-matplotlib >= 2.2.2
|
||||
Recommends: python-numpy
|
||||
@ -58,16 +57,17 @@ BuildRequires: %{python_module Pillow}
|
||||
BuildRequires: %{python_module ipykernel}
|
||||
BuildRequires: %{python_module ipython}
|
||||
BuildRequires: %{python_module ipywidgets}
|
||||
BuildRequires: %{python_module jupyter}
|
||||
BuildRequires: %{python_module matplotlib}
|
||||
BuildRequires: %{python_module narwhals}
|
||||
BuildRequires: %{python_module numpy}
|
||||
BuildRequires: %{python_module pandas}
|
||||
BuildRequires: %{python_module pdfrw}
|
||||
BuildRequires: %{python_module psutil}
|
||||
BuildRequires: %{python_module pyshp}
|
||||
BuildRequires: %{python_module pytest}
|
||||
BuildRequires: %{python_module pytz}
|
||||
BuildRequires: %{python_module requests}
|
||||
BuildRequires: %{python_module scikit-image}
|
||||
BuildRequires: %{python_module scikit-image if %python-base < 3.13}
|
||||
BuildRequires: %{python_module scipy}
|
||||
BuildRequires: %{python_module statsmodels}
|
||||
BuildRequires: %{python_module xarray}
|
||||
@ -83,30 +83,8 @@ Python API allows you to access all of Plotly's functionality from Python.
|
||||
Plotly figures are shared, tracked, and edited all online and the data is
|
||||
always accessible from the graph.
|
||||
|
||||
%package jupyter
|
||||
Summary: Jupyter notebook integration for %{name}
|
||||
Requires: %{name} = %{version}
|
||||
Requires: jupyter-plotly = %{version}
|
||||
# So that any of the flavor satisifies the jupyter package
|
||||
Provides: jupyterpython(plotly-jupyter) = %{version}
|
||||
Requires: python-ipywidgets >= 7.6
|
||||
Requires: (python-jupyterlab >= 3 or python-notebook >= 5.3)
|
||||
Provides: python-jupyterlab-plotly = %{version}-%{release}
|
||||
|
||||
%description jupyter
|
||||
Use this package to make collaborative, interactive,
|
||||
publication-quality graphs from Python on https://plot.ly.
|
||||
|
||||
Plotly is an online collaborative data analysis and graphing tool. The
|
||||
Python API allows you to access all of Plotly's functionality from Python.
|
||||
Plotly figures are shared, tracked, and edited all online and the data is
|
||||
always accessible from the graph.
|
||||
|
||||
This package provides Jupyterlab and Notebook integration and widgets.
|
||||
|
||||
%package -n jupyter-plotly
|
||||
Summary: Jupyter notebook integration for %{name}
|
||||
Requires: jupyterpython(plotly-jupyter) = %{version}
|
||||
Summary: Jupyter integration for %{name}
|
||||
Provides: jupyterlab-plotly = %{version}-%{release}
|
||||
|
||||
%description -n jupyter-plotly
|
||||
@ -119,14 +97,12 @@ Plotly figures are shared, tracked, and edited all online and the data is
|
||||
always accessible from the graph.
|
||||
|
||||
This package provides the flavorless configuration for the
|
||||
Jupyterlab and Notebook integration and widgets.
|
||||
Jupyterlab integration and widgets.
|
||||
|
||||
%prep
|
||||
%autosetup -p4 -n plotly.py-%{version}/packages/python/plotly
|
||||
pushd ../../javascript/jupyterlab-plotly/
|
||||
%autosetup -p4 -n plotly.py-%{version}
|
||||
pushd js
|
||||
rm package-lock.json
|
||||
# allow builder v4
|
||||
sed -i '/jupyterlab.builder/ s/\^3/>=3/' package.json
|
||||
local-npm-registry %{_sourcedir} install --include=dev --include=peer
|
||||
popd
|
||||
# remove script interpreter line in non-executable script
|
||||
@ -141,11 +117,12 @@ find . -name __init__.py -exec touch -m -r plotly/__init__.py '{}' ';'
|
||||
%pyproject_install
|
||||
%python_expand %fdupes %{buildroot}%{$python_sitelib}
|
||||
%fdupes %{buildroot}%{_jupyter_prefix}
|
||||
%python_clone -a %{buildroot}%{_bindir}/plotly_get_chrome
|
||||
|
||||
%check
|
||||
# API parameter mismatch
|
||||
donttest="test_described_subscript_error_on_type_error"
|
||||
%pytest plotly/tests/test_core -k "not ($donttest)"
|
||||
%pytest tests/test_core -k "not ($donttest)"
|
||||
# not available
|
||||
donttest="test_kaleido"
|
||||
donttest="$donttest or test_px_input and (vaex or polars)"
|
||||
@ -155,23 +132,23 @@ donttest="$donttest or test_matplotlylib"
|
||||
donttest="$donttest or test_masked_constants_example"
|
||||
# flaky timing error
|
||||
donttest="$donttest or test_fast_track_finite_arrays"
|
||||
%pytest plotly/tests/test_optional -k "not ($donttest)"
|
||||
# no python313-scikit-image yet
|
||||
python313_donttest=" or TestTernarycontour"
|
||||
|
||||
# Optional dependencies not yet in openSUSE, requires python-polars
|
||||
# --ignore doesn't work because the import is in the conftest.py
|
||||
rm -rf tests/test_optional/test_px/
|
||||
%pytest tests/test_optional -k "not ($donttest ${$python_donttest})"
|
||||
|
||||
%files %{python_files}
|
||||
%license LICENSE.txt
|
||||
%{python_sitelib}/_plotly_future_/
|
||||
%{python_sitelib}/_plotly_utils/
|
||||
%{python_sitelib}/plotly/
|
||||
%{python_sitelib}/plotly-%{version}.dist-info
|
||||
|
||||
%files %{python_files jupyter}
|
||||
%license LICENSE.txt
|
||||
%{python_sitelib}/jupyterlab_plotly
|
||||
%python_alternative %{_bindir}/plotly_get_chrome
|
||||
|
||||
%files -n jupyter-plotly
|
||||
%license LICENSE.txt
|
||||
%{_jupyter_nbextension_dir}/jupyterlab-plotly/
|
||||
%{_jupyter_labextensions_dir3}/jupyterlab-plotly/
|
||||
%{_jupyter_config} %{_jupyter_nb_notebook_confdir}/jupyterlab-plotly.json
|
||||
|
||||
%changelog
|
||||
|
Loading…
x
Reference in New Issue
Block a user