Skip to content

Commit 682bcb1

Browse files
authored
Merge pull request #6707 from LMFDB/main
2 parents 64c4529 + df47d42 commit 682bcb1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1392
-33
lines changed

.devcontainer/devcontainer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
},
99
"postCreateCommand": "/bin/bash .devcontainer/setup.sh",
1010
"postAttachCommand": {
11-
"server": "sage -python start-lmfdb.py --debug",
11+
"server": "sage -python start-lmfdb.py --debug"
1212
},
1313
"forwardPorts": [37777],
1414
"customizations": {
@@ -25,4 +25,4 @@
2525
}
2626
}
2727
}
28-
}
28+
}

.environment.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,4 @@ dependencies:
1616
- flask
1717
- werkzeug
1818
- parallel
19+
- pari-elldata
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: 'Snippet Setup'
2+
description: 'Set up LMFDB environment for generating snippets'
3+
4+
runs:
5+
using: 'composite'
6+
steps:
7+
- uses: actions/checkout@v3
8+
9+
- uses: conda-incubator/setup-miniconda@v2
10+
with:
11+
activate-environment: lmfdb
12+
auto-activate-base: false
13+
# environment-file: .environment.yml # now we install after cache
14+
channel-priority: strict
15+
# IMPORTANT: use-only-tar-bz2: true needs to be set for caching to work properly!
16+
use-only-tar-bz2: false
17+
18+
- name: Cache conda
19+
uses: actions/cache@v3
20+
id: condacache
21+
env:
22+
# Increase this value to reset cache if .environment.yml has not changed
23+
CACHE_NUMBER: 0
24+
with:
25+
path: |
26+
/usr/share/miniconda/envs/lmfdb
27+
key:
28+
${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{
29+
hashFiles('.environment.yml') }}
30+
31+
- name: Install Julia
32+
uses: julia-actions/setup-julia@v2
33+
with:
34+
version: '1' # latest version
35+
36+
- name: Load Julia packages from cache
37+
id: julia-cache
38+
uses: julia-actions/cache@v2
39+
40+
- name: Install Oscar
41+
shell: bash -l {0}
42+
run: |
43+
julia -e 'using Pkg; Pkg.add("Oscar"); using Oscar'
44+
45+
- name: Run install script
46+
shell: bash -l {0}
47+
# Only need to run install when deps has been changed
48+
if: steps.condacache.outputs.cache-hit != 'true'
49+
run: conda env create -f .environment.yml || conda env update -f .environment.yml
50+
51+
- name: Show conda info
52+
shell: bash -l {0}
53+
run: |
54+
conda info
55+
conda list
56+
57+
- name: Cache pip
58+
uses: actions/cache@v3
59+
with:
60+
# This path is specific to Ubuntu
61+
path: ~/.cache/pip
62+
# Look to see if there is a cache hit for the corresponding requirements file
63+
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
64+
restore-keys: |
65+
${{ runner.os }}-pip-
66+
${{ runner.os }}-
67+
68+
- name: pip stuff
69+
shell: bash -l {0}
70+
run: |
71+
sage -pip install -r requirements.txt
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Generate Snippet Code Files
2+
3+
on:
4+
push:
5+
paths:
6+
- '**/code*.yaml'
7+
8+
jobs:
9+
snippet-generate:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout code
13+
uses: actions/checkout@v4 # Or a specific version
14+
15+
- name: Set up environment
16+
uses: ./.github/actions/snippet_setup
17+
18+
- name: Generate snippets
19+
if: matrix.files != 'lint'
20+
shell: bash -l {0}
21+
run: |
22+
sage -python lmfdb/tests/generate_snippet_tests.py generate -i magma
23+
24+
- name: Create Pull Request
25+
uses: peter-evans/create-pull-request@v7
26+
with:
27+
commit-message: snippet code test files generated by action
28+
title: Code snippets from snippet-generate action
29+
body: This is an auto-generated PR with code snippets from yaml files
30+
labels: code snippets, automated pr

.github/workflows/snippet_test.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Test Snippet Code files
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 1,15 * *'
6+
workflow_dispatch: {}
7+
8+
jobs:
9+
snippet-test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout code
13+
uses: actions/checkout@v4 # Or a specific version
14+
15+
- name: Set up environment
16+
uses: ./.github/actions/snippet_setup
17+
18+
- name: Test snippets
19+
if: matrix.files != 'lint'
20+
id: testing_step
21+
shell: bash -l {0}
22+
run: |
23+
sage -python lmfdb/tests/generate_snippet_tests.py generate -i magma -e snippet_error_file.md
24+
25+
- name: Read error file
26+
if: ${{ hashFiles('**/snippet_error_file.md') }}
27+
id: read_error_file
28+
run: |
29+
{
30+
echo 'ERROR_CONTENTS<<EOF'
31+
cat snippet_error_file.md
32+
echo EOF
33+
} >> "$GITHUB_OUTPUT"
34+
35+
- name: Create or update snippet error issue
36+
if: ${{ hashFiles('**/snippet_error_file.md') }}
37+
uses: ovsds/create-or-update-unique-issue-action@v1
38+
with:
39+
title: "(Auto-generated) Errors in code snippets"
40+
body: ${{ steps.read_error_file.outputs.ERROR_CONTENTS }}
41+
unique-title-includes: "(Auto-generated) Errors in code snippets"
42+
43+
- name: Delete error log file
44+
if: ${{ hashFiles('**/snippet_error_file.md') }}
45+
shell: bash -l {0}
46+
run: |
47+
rm snippet_error_file.md
48+
49+
- name: Check for diff
50+
id: diff_check
51+
run: |
52+
# Get the diff and save it to a file.
53+
git diff --relative --exit-code > changes.diff
54+
55+
- name: Report diff
56+
if: ${{ failure() && steps.diff_check.conclusion == 'failure' }}
57+
run: echo "::warning::Nontrivial diff detected. See the 'repo-diff' artifact for details."
58+
59+
- name: Upload diff as artifact
60+
if: ${{ failure() && steps.diff_check.conclusion == 'failure' }}
61+
uses: actions/upload-artifact@v4
62+
with:
63+
name: repo-diff
64+
path: changes.diff

CONTRIBUTORS.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ name: John Cremona
114114
affil: University of Warwick
115115
url: https://www2.warwick.ac.uk/fac/sci/maths/people/staff/john_cremona/
116116
---
117+
name: Håvard Damm-Johnsen
118+
affil: University of Gothenburg
119+
url: https://havarddj.github.io/
120+
---
117121
name: Rachel Davis
118122
affil: Purdue University
119123
url: https://www.math.purdue.edu/~davis705

lmfdb/api/api.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from psycopg2.extensions import QueryCanceledError
77
from lmfdb import db
88
from psycodict.encoding import Json
9-
from lmfdb.utils import flash_error
9+
from lmfdb.utils import flash_error, comma
1010
from lmfdb.utils.datetime_utils import utc_now_naive
1111
from flask import (render_template, request, url_for, current_app,
1212
abort, redirect, Response)
@@ -137,11 +137,11 @@ def split_db(tablename):
137137
'tablespace': tablespaces.get(tablename, ""),
138138
}
139139
dataSize = size - indexSize
140-
info['ntables'] = len(table_sizes)
141-
info['nobjects'] = nobjects
142-
info['size'] = mb(size)
143-
info['dataSize'] = mb(dataSize)
144-
info['indexSize'] = mb(indexSize)
140+
info['ntables'] = comma(len(table_sizes))
141+
info['nobjects'] = comma(nobjects)
142+
info['size'] = comma(mb(size))
143+
info['dataSize'] = comma(mb(dataSize))
144+
info['indexSize'] = comma(mb(indexSize))
145145
if info['sortby'] == 'name':
146146
sortedkeys = sorted(stats)
147147
elif info['sortby'] == 'objects' and info['groupby'] == 'db':

lmfdb/app.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,7 @@ def WhiteListedRoutes():
719719
'Character/calc-jacobi/Dirichlet',
720720
'Character/calc-kloosterman/Dirichlet',
721721
'Character/calc-value/Dirichlet',
722+
'datasets',
722723
'EllipticCurve',
723724
'Field',
724725
'GaloisGroup',
@@ -774,6 +775,7 @@ def WhiteListedRoutes():
774775
'news',
775776
'not_yet_implemented',
776777
'random',
778+
'rcs',
777779
'robots.txt',
778780
'search',
779781
'sitemap',

lmfdb/classical_modular_forms/code-form.yaml

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,23 +43,35 @@ dimensions-spaces:
4343
mfdim([N,k,chi],1) \\ Cusps
4444
mfdim([N,k,chi],0) \\ New
4545
46-
initialize-newspace:
46+
initialize-newspace-common: &initialize-newspace-common
4747
comment: Compute space of new eigenforms
4848
pari: |
4949
[N,k,chi] = [{N},{k},Mod({conrey_index},{N})]
5050
mf = mfinit([N,k,chi],0)
5151
lf = mfeigenbasis(mf)
52-
sage: |
53-
from sage.modular.dirichlet import DirichletCharacter
54-
H = DirichletGroup({N}, base_ring=CyclotomicField({sage_zeta_order}))
55-
chi = DirichletCharacter(H, H._module({sage_genvalues}))
56-
N = Newforms(chi, {k}, names="a")
5752
magma: |
5853
//Please install CHIMP (https://github.com/edgarcosta/CHIMP) if you want to run this code
5954
chi := DirichletCharacter("{N}.{conrey_index}");
6055
S:= CuspForms(chi, {k});
6156
N := Newforms(S);
6257
58+
initialize-newspace-weight-1:
59+
<<: *initialize-newspace-common
60+
sage: |
61+
from sage.modular.dirichlet import DirichletCharacter
62+
H = DirichletGroup({N}, base_ring=CyclotomicField({sage_zeta_order}))
63+
chi = DirichletCharacter(H, H._module({sage_genvalues}))
64+
B = ModularForms(chi, 1).cuspidal_submodule().basis()
65+
N = [B[i] for i in range(len(B))]
66+
67+
initialize-newspace-weight-not-1:
68+
<<: *initialize-newspace-common
69+
sage: |
70+
from sage.modular.dirichlet import DirichletCharacter
71+
H = DirichletGroup({N}, base_ring=CyclotomicField({sage_zeta_order}))
72+
chi = DirichletCharacter(H, H._module({sage_genvalues}))
73+
N = Newforms(chi, {k}, names="a")
74+
6375
coeff-field:
6476
comment: Coefficient field, relative polynomial
6577
pari: |

lmfdb/classical_modular_forms/main.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,33 @@ def parse_prec(info):
306306
return []
307307

308308

309+
def validate_format_parameter(format_param):
310+
"""
311+
Validate the format parameter for newform display.
312+
313+
Args:
314+
format_param: The format parameter to validate
315+
316+
Returns:
317+
str: validated format parameter (defaults to 'embed' if None or invalid)
318+
319+
Side effects:
320+
Flashes error message if format parameter is invalid
321+
"""
322+
valid_formats = ['embed', 'analytic_embed', 'satake', 'satake_angle']
323+
324+
# Default to 'embed' if format is None
325+
if format_param is None:
326+
return 'embed'
327+
328+
# Check if format is valid
329+
if format_param not in valid_formats:
330+
flash_error("Invalid format parameter '%s'. Valid formats are: %s" % (format_param, ', '.join(valid_formats)))
331+
format_param = 'embed'
332+
333+
return format_param
334+
335+
309336
def eta_quotient_texstring(etadata):
310337
r"""
311338
Returns a latex string representing an eta quotient.
@@ -357,7 +384,9 @@ def render_newform_webpage(label):
357384

358385
info = to_dict(request.args)
359386
info['display_float'] = display_float
360-
info['format'] = info.get('format', 'embed')
387+
388+
# Validate format parameter
389+
info['format'] = validate_format_parameter(info.get('format'))
361390

362391
if label in ETAQUOTIENTS:
363392
info['eta_quotient'] = eta_quotient_texstring(ETAQUOTIENTS[label])

0 commit comments

Comments
 (0)