Refactoring du processus d'import par url:

- on utilise tout le temps celery
- on propose un import par lot
- on remercie l'utilisateur et on l'informe des urls prises en compte ou non
This commit is contained in:
Jean-Marie Favreau 2024-08-15 22:32:42 +02:00
parent b9c63219bb
commit ca1db6890d
9 changed files with 675 additions and 402 deletions

View File

@ -199,6 +199,45 @@ def weekly_imports(self):
run_recurrent_import.delay(imp.pk)
@app.task(base=ChromiumTask, bind=True)
def import_events_from_urls(self, urls_and_cats):
from agenda_culturel.models import Event, Category
for ucat in urls_and_cats:
if ucat is not None:
url = ucat[0]
cat = ucat[1]
url = Extractor.clean_url(url)
# we check if the url is known
existing = Event.objects.filter(uuids__contains=[url])
# if it's unknown
if len(existing) == 0:
u2e = URL2Events(ChromiumHeadlessDownloader(), single_event=True)
events_structure = u2e.process(
url, published=False
)
# TODO: use celery to import the associated events
if (
events_structure is not None
and "events" in events_structure
and len(events_structure["events"]) > 0
):
event = Event.from_structure(
events_structure["events"][0],
events_structure["header"]["url"],
)
if event is not None:
if (event.category is None or event.category == Category.get_default_category()):
if cat is not None:
event.category = Category.objects.filter(name=cat).first()
event.save()
logger.info('Successful import from ' + url)
app.conf.beat_schedule = {
"daily_imports": {
"task": "agenda_culturel.celery.daily_imports",

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="96.291573mm"
height="56.166805mm"
viewBox="0 0 96.291582 56.166805"
version="1.1"
id="svg5"
xml:space="preserve"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
sodipodi:docname="merci.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="1.3189567"
inkscape:cx="104.24906"
inkscape:cy="-20.091638"
inkscape:window-width="1920"
inkscape:window-height="1020"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g384" /><defs
id="defs2"><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter38466-3"
x="-0.060800897"
y="-0.25262014"
width="1.1216247"
height="1.5052374"><feGaussianBlur
inkscape:collect="always"
stdDeviation="0.81073628"
id="feGaussianBlur38468-6" /></filter><filter
inkscape:collect="always"
style="color-interpolation-filters:sRGB"
id="filter38466-3-5"
x="-0.060800895"
y="-0.25262014"
width="1.1216247"
height="1.5052374"><feGaussianBlur
inkscape:collect="always"
stdDeviation="0.81073628"
id="feGaussianBlur38468-6-3" /></filter></defs><g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-56.292353,-59.875625)"><g
id="g384"
transform="translate(22.72439,-118.49779)"><path
style="fill:#008000;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 78.595236,189.74139 c 1.637421,-4.59024 2.912742,-7.06191 5.749725,-8.47307 5.268285,-2.62054 9.623617,-2.69186 15.476304,-2.08514 3.422645,0.35481 6.886145,2.32348 9.257535,4.56744 -6.13616,1.90424 -8.28801,4.46745 -12.838753,5.36178 -5.774877,1.13491 -11.763207,0.41933 -17.644811,0.62899"
id="path1596"
sodipodi:nodetypes="cccccc" /><path
style="fill:#010000;fill-opacity:0.561232;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter38466-3)"
d="m 61.796221,229.14122 c 0.965519,4.45831 25.019863,3.96877 30.482693,1.22894 13.879366,-2.9076 -16.08645,-5.72863 -22.936483,-6.13413 -4.613953,0.0322 -8.095357,1.93397 -7.54621,4.90519 z"
id="path38464-7"
sodipodi:nodetypes="cccc" /><path
style="fill:#010000;fill-opacity:0.561232;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter38466-3-5)"
d="m 39.807813,223.56146 c 0.965519,4.45831 25.019863,3.96877 30.482693,1.22894 13.879368,-2.9076 -16.08645,-5.72863 -22.936483,-6.13413 -4.613953,0.0322 -8.095357,1.93397 -7.54621,4.90519 z"
id="path38464-7-5"
sodipodi:nodetypes="cccc" /><path
style="fill:#840103;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 61.349027,222.15794 c 0.708759,2.00893 -16.515833,0.34774 -21.687027,-7.93835 -5.171194,-8.2861 -3.763967,-13.58169 -2.234075,-17.59746 1.529892,-4.01577 2.907438,-5.92547 5.806876,-8.7927 2.899438,-2.86723 5.998448,-8.59829 11.9153,-8.91316 5.916851,-0.31487 13.246677,1.03438 18.14476,6.51896 4.898083,5.48457 4.135783,4.56309 4.327753,11.82129 0.19197,7.2582 -16.982346,22.89249 -16.273587,24.90142 z"
id="path38521"
sodipodi:nodetypes="zzzzzzzz" /><path
style="fill:#a30b0e;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 65.673042,229.32826 c 0,0 2.096979,0.98865 3.366175,1.05833 1.269196,0.0697 2.515497,-0.62306 4.020413,-0.79375 1.504916,-0.17069 3.315514,-0.33009 4.986984,-0.15445 1.67146,0.17564 2.67655,1.44596 4.94818,1.21279 2.27163,-0.23317 4.7873,-0.53519 7.76883,-3.24162 2.98153,-2.70643 6.67077,-9.99926 8.01766,-13.7903 1.346886,-3.79104 0.964,-6.95292 0.88227,-8.76492 -0.0817,-1.812 -0.28545,-2.05058 -0.28545,-2.05058"
id="path6267"
sodipodi:nodetypes="czzzzzzzc" /><path
style="fill:#c07f16;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 71.812371,190.61847 c 1.858659,0.51169 3.166323,1.18081 5.616683,1.52344 1.36291,-0.20833 2.52486,-0.13533 4.31769,-0.94554 l -1.36453,9.43662 c 0,0 -6.727792,0.0977 -6.541247,-0.54771 0.186544,-0.6454 -2.028596,-9.46681 -2.028596,-9.46681 z"
id="path24930"
sodipodi:nodetypes="ccccsc" /><path
style="fill:#f1e890;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 78.082684,198.37205 c -1.28283,-3.55228 -5.226566,-9.29945 -10.596971,-8.55496 -5.370405,0.74449 -10.078575,7.90246 -10.928331,15.43409 -0.849756,7.53163 7.401814,24.34497 10.192223,24.52944 3.229996,0.55392 5.958819,-1.60562 6.699335,-2.56442 0.740516,-0.9588 1.0542,1.41933 1.880334,1.58911 0.82614,0.16978 1.47736,-1.00863 2.48529,-0.75867 1.00793,0.24996 4.01972,2.24324 6.05234,1.00663 8.40879,-5.32292 15.92933,-15.39837 15.55298,-25.19132 -0.22977,-5.9788 -4.35586,-13.60403 -10.22824,-14.75036 -6.96794,-1.3602 -9.33036,3.99209 -11.10896,9.26046 z"
id="path6257"
sodipodi:nodetypes="czzczzzcssc" /><path
style="fill:#744e0b;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 77.313734,188.64368 -0.42521,-1.38416 0.9446,-0.48098 0.84134,0.21637 0.0662,5.23515 v 3.40759 c -0.36705,0.23459 -0.84847,0.0157 -1.32294,-0.17562 -3e-5,-0.13276 -0.10399,-6.81835 -0.10399,-6.81835 z"
id="path6259"
sodipodi:nodetypes="cccccccc" /><path
style="fill:#60140f;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 82.946843,205.63036 c -0.10793,0.44487 -0.0918,0.80693 -0.0505,1.30309 0.0413,0.49616 -0.27564,1.44483 0.34253,1.64797 0.61817,0.20314 1.44979,-0.60075 1.65368,-1.48252 0.20389,-0.88177 -1.27069,-2.87462 -1.27069,-2.87462 0,0 -0.56709,0.96121 -0.67502,1.40608 z"
id="path6261"
sodipodi:nodetypes="zzzzcz" /><path
style="fill:#60140f;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 72.30932,204.58819 c -0.53143,0.0298 -0.217288,0.3086 -0.396875,0.76536 -0.179587,0.45676 -0.855987,1.48491 -0.557202,2.00672 0.298785,0.52181 1.011637,0.57281 1.473936,0.39196 0.462302,-0.18085 0.786262,-0.59664 0.778252,-1.22739 -0.008,-0.63075 -0.766681,-1.96648 -1.298111,-1.93665 z"
id="path6263"
sodipodi:nodetypes="zzzzzz" /><path
style="fill:#f5dc0c;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 77.682294,200.72052 -0.81262,4.57009 -0.31681,6.97364 0.99998,3.92596 0.75482,-4.71212 -0.0384,-3.55499 z"
id="path6265" /><path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 41.991603,198.95761 c 0,0 4.204417,-1.16049 5.95753,-1.68797 0.53786,-0.16183 0.794335,-3.57452 0.695045,-3.97169 -0.09929,-0.39717 -1.092213,-2.4823 -1.092213,-2.4823"
id="path39627"
sodipodi:nodetypes="cszc" /><path
style="fill:#510701;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 47.80348,196.5405 c -0.105315,-0.14042 -1.841212,-1.73181 -2.632882,-2.7733 -0.79167,-1.04149 -1.693987,-2.52693 -2.071198,-3.45155 -0.377211,-0.92462 -0.738993,-1.48616 -0.456366,-1.91264 0.282627,-0.42648 0.734231,-0.30422 1.088257,-0.18241 0.354026,0.12181 0.684882,0.55237 0.772311,0.84252 0.08743,0.29015 -0.119676,0.3973 -0.105315,0.667 0.01436,0.2697 -0.04559,0.27495 0.245735,0.91273 0.291328,0.63778 1.160067,1.94648 1.825466,2.70309 0.665399,0.75661 1.859099,1.04674 2.088991,1.83989 0.229892,0.79315 -0.09265,2.0968 -0.609346,2.08381 -0.516692,-0.013 -0.215863,-0.90466 -0.215863,-0.90466"
id="path39629"
sodipodi:nodetypes="czzzzzzzzzzc" /><path
style="fill:#ff6600;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 103.98789,206.44948 -5.111645,15.83899 c 0,0 6.647825,-5.08721 5.653415,-2.65705 -2.93215,7.16558 3.44504,-11.15811 3.44504,-11.15811 z"
id="path3853"
sodipodi:nodetypes="ccscc" /><g
id="g1540"
transform="rotate(18.710832,138.65558,232.66702)"><rect
style="fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1"
id="rect624"
width="37.333855"
height="22.292042"
x="80.918617"
y="198.86351"
ry="3.0437441" /><g
aria-label="Merci !"
id="text1442"
style="font-weight:bold;font-size:9.51886px;font-family:'Comic Sans MS';-inkscape-font-specification:'Comic Sans MS, Bold';stroke-width:0.238347"><path
d="m 86.718914,209.92516 q -0.209154,0.75296 -0.585633,2.27281 -0.08831,0.52521 -0.171971,1.04578 -0.190564,0.65999 -0.70183,0.65999 -0.320704,0 -0.506619,-0.21845 -0.158028,-0.18591 -0.158028,-0.44154 0,-0.75296 0.320703,-1.83592 0.478732,-1.62211 0.515915,-1.79873 0.134789,-0.71577 0.274225,-1.43154 0.209155,-0.98535 0.450845,-1.31071 0.246337,-0.33 0.618168,-0.33 0.422957,0 0.622816,0.42761 0.185915,0.40436 0.399718,1.65464 0.204506,1.2131 0.608872,2.61211 0.529858,-1.38042 0.985351,-3.03041 l 0.260281,-1.06902 q 0.250986,-0.66464 0.776196,-0.66464 0.506619,0 0.752957,0.77154 0.102253,0.31141 0.21845,1.16197 0.269577,1.98 0.678591,3.39296 0.413661,1.43619 0.413661,1.56169 0,0.27422 -0.21845,0.46014 -0.204507,0.16732 -0.46014,0.16732 -0.506619,0 -0.752957,-0.72507 l -0.260281,-1.12479 q -0.223099,-0.83662 -0.48338,-2.40295 -0.209155,0.62281 -0.692534,1.95676 l -0.278873,0.85521 q -0.171972,0.50661 -0.357887,0.83197 -0.246338,0.43225 -0.687886,0.43225 -0.436901,0 -0.669295,-0.51592 l -0.260282,-0.8645 q -0.362534,-1.18986 -0.650703,-2.50056 z"
id="path1507" /><path
d="m 95.480169,213.81079 q -1.110844,0 -1.817321,-0.52986 -0.780844,-0.58563 -0.780844,-1.65 0,-1.17591 0.618168,-1.98929 0.687886,-0.90169 1.854504,-0.90169 0.808731,0 1.343238,0.26028 0.70183,0.34394 0.70183,1.06901 0,0.51127 -0.57169,0.90634 -0.260281,0.18127 -1.045773,0.52986 l -1.566336,0.69253 q 0.223099,0.24169 0.539155,0.36254 0.316055,0.12084 0.725069,0.12084 0.622816,0 1.055069,-0.25563 0.385774,-0.22775 0.618168,-0.22775 0.48338,0 0.48338,0.46944 0,0.52986 -0.776196,0.8645 -0.650704,0.27888 -1.380421,0.27888 z m -0.125493,-3.94605 q -0.432253,0 -0.739013,0.28817 -0.30676,0.28816 -0.492675,0.8645 0.52521,-0.22775 1.045773,-0.45084 0.627464,-0.28352 0.999294,-0.52521 -0.311408,-0.17662 -0.813379,-0.17662 z"
id="path1509" /><path
d="m 102.35438,210.24586 q -0.0418,0.71113 -0.64605,0.71113 -0.58563,0 -0.58563,-0.60423 l -0.0232,-0.46943 q -1.04578,0.16732 -1.496621,1.07366 l 0.0046,2.33788 q 0,0.26493 -0.181268,0.4369 -0.181267,0.17662 -0.46014,0.17662 -0.288168,0 -0.446196,-0.18591 -0.148733,-0.16733 -0.148733,-0.42761 v -3.04436 q 0,-0.14408 0.0093,-0.4276 0.0093,-0.28817 0.0093,-0.43226 0,-0.26028 0.15338,-0.43225 0.158028,-0.17662 0.446197,-0.17662 0.515914,0 0.61352,0.52986 0.822671,-0.61352 1.826621,-0.61352 0.92957,0 0.92957,1.23633 0,0.23705 -0.005,0.31141 z"
id="path1511" /><path
d="m 105.171,213.8898 q -1.02253,0 -1.71507,-0.58098 -0.72971,-0.61352 -0.72971,-1.61747 0,-0.92492 0.65535,-1.91028 0.74366,-1.12478 1.72901,-1.12478 0.48338,0 1.12943,0.26028 0.78549,0.3207 0.78549,0.73901 0,0.22775 -0.15802,0.40437 -0.16733,0.19056 -0.43226,0.19056 -0.19985,0 -0.48338,-0.2138 -0.27887,-0.21845 -0.84126,-0.21845 -0.35789,0 -0.7762,0.70183 -0.39972,0.67859 -0.39972,1.17126 0,0.48803 0.35324,0.7669 0.33465,0.26493 0.8831,0.26493 0.31141,0 0.76225,-0.23704 0.45085,-0.23704 0.57169,-0.23704 0.25099,0 0.42761,0.18127 0.18126,0.18126 0.18126,0.41366 0,0.36253 -0.79014,0.72507 -0.70647,0.3207 -1.15267,0.3207 z"
id="path1513" /><path
d="m 108.98226,208.01023 q -0.29746,0 -0.51591,-0.19986 -0.21845,-0.19986 -0.21845,-0.48802 0,-0.28817 0.21845,-0.48803 0.21845,-0.19986 0.51591,-0.19986 0.29747,0 0.51127,0.19986 0.21845,0.19986 0.21845,0.48803 0,0.28816 -0.21845,0.48802 -0.2138,0.19986 -0.51127,0.19986 z m 0.39507,3.4069 q 0,0.26493 0.0139,0.85056 0.0186,0.58563 0.0186,0.85056 0,0.26958 -0.18127,0.4462 -0.18127,0.17197 -0.46014,0.17197 -0.27887,0 -0.46014,-0.17197 -0.18127,-0.17662 -0.18127,-0.4462 0,-0.26493 -0.0186,-0.85056 -0.0139,-0.58563 -0.0139,-0.85056 0,-0.41366 0.0465,-1.03648 0.0465,-0.62281 0.0465,-1.03648 0,-0.26957 0.18126,-0.44154 0.18127,-0.17662 0.46014,-0.17662 0.27888,0 0.46014,0.17662 0.18127,0.17197 0.18127,0.44154 0,0.41367 -0.0465,1.03648 -0.0465,0.62282 -0.0465,1.03648 z"
id="path1515" /><path
d="m 115.36845,212.21656 q -0.26028,0 -0.43225,-0.16267 -0.16733,-0.16268 -0.16733,-0.40902 0,-0.18126 -0.0139,-0.53915 -0.009,-0.36253 -0.009,-0.5438 0,-0.64141 0.009,-1.92422 0.0139,-1.28282 0.0139,-1.92423 0,-0.24633 0.17198,-0.40901 0.17197,-0.16732 0.4276,-0.16732 0.25563,0 0.42761,0.16732 0.17197,0.16268 0.17197,0.40901 v 4.9314 q 0,0.24634 -0.17197,0.40902 -0.16733,0.16267 -0.42761,0.16267 z m -0.0139,1.68718 q -0.27888,0 -0.52057,-0.29746 -0.21845,-0.27422 -0.21845,-0.51127 0,-0.24169 0.19057,-0.40436 0.19056,-0.16268 0.43225,-0.16268 0.27887,0 0.51592,0.29747 0.21845,0.27422 0.21845,0.50662 0,0.23704 -0.19057,0.40436 -0.18591,0.16732 -0.4276,0.16732 z"
id="path1517" /></g></g><path
style="fill:#007700;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
d="m 43.963481,192.38257 c -8.814017,3.40711 -10.967105,13.7965 -9.43133,18.16737 1.535776,4.37087 2.112699,8.01053 6.643607,9.05239 -1.873669,-6.18344 -0.699401,-9.06026 -0.247367,-13.55754 0.466564,-4.6417 3.297172,-7.78272 3.03509,-13.66222"
id="path1596-0"
sodipodi:nodetypes="czcac" /><path
d="m 94.587389,218.65885 c 0,0 0.953693,-5.7278 5.877331,-6.4571 0,0 4.46881,0.76778 4.5444,2.17455 0,0 4.70056,-0.0156 3.84696,3.2503 0,0 -0.0752,1.38167 -1.38138,1.78383 0,0 2.51238,1.65759 0.30205,3.76813 l -1.85882,0.92978 c 0,0 0.95503,2.63758 -2.05946,3.06512 0,0 -1.02987,0.60307 -2.26096,-0.37646 0,0 -4.069454,1.18135 -6.406305,-2.46086 0,0 -1.808924,-1.23065 -0.603816,-5.67729"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
id="path2902" /><path
d="m 94.587389,218.65885 c 0,0 0.953693,-5.7278 5.877331,-6.4571 0,0 4.40973,0.63603 4.48532,2.0428 0,0 4.75964,0.11615 3.90604,3.38205 0,0 -0.0752,1.38167 -1.38138,1.78383 0,0 2.51238,1.65759 0.30205,3.76813 l -1.85882,0.92978 c 0,0 0.95503,2.63758 -2.05946,3.06512 0,0 -1.02987,0.60307 -2.26096,-0.37646 0,0 -4.069454,1.18135 -6.406305,-2.46086 0,0 -1.808924,-1.23065 -0.603816,-5.67729 z"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2904"
sodipodi:nodetypes="ccccccccccc" /><path
d="m 104.95004,214.24455 c 0.12844,1.47744 -0.91771,2.46285 -1.55157,3.58466 -0.73408,1.29954 -0.19399,3.72087 -2.23543,3.93879 -4.443922,0.47457 -2.310651,-6.60468 -0.33428,-7.34448"
style="fill:#ffffff;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2906"
sodipodi:nodetypes="cccc" /><path
d="m 98.668772,217.16207 c -0.496418,-0.43585 -0.540213,-1.12366 -0.32686,-1.75843"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2908" /><path
d="m 107.4747,219.41043 c -1.16386,0.58644 -4.29829,0.35908 -4.4022,-0.65987"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2910"
sodipodi:nodetypes="cc" /><path
d="m 106.73371,223.61694 c -2.06624,0.79858 -4.07457,0.11332 -4.97428,-1.75769"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2912" /><path
style="fill:#ff6600;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 98.876245,222.28847 v 0 l -1.624195,5.28296 c -0.12264,1.25072 3.60773,2.76629 3.83615,1.12175 0.005,-0.0357 0.30602,-0.79593 0.66435,-1.79926 -3.37616,-3.34464 -1.42049,-4.22503 -2.876305,-4.60545 z"
id="path3853-6-4"
sodipodi:nodetypes="cccscc" /><path
d="m 100.08014,221.79543 c -1.90604,1.60694 1.81991,5.20252 1.67241,5.09849"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2914"
sodipodi:nodetypes="cc" /><path
d="m 98.945728,221.08094 c -0.494546,0.24978 -1.143288,0.65344 -1.783528,0.47759"
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path2916" /><path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
d="m 99.192188,221.24361 v 0 l -1.940147,6.32782 c -0.26565,1.38741 3.497779,2.57455 3.836159,1.12175 0.008,-0.0351 0.30602,-0.79593 0.66435,-1.79926"
id="path3853-6"
sodipodi:nodetypes="cccsc" /></g></g></svg>

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -23,7 +23,8 @@
<p>On peut importer automatiquement un événement depuis d'autres sites internet (principalement depuis Facebook pour
l'instant), à partir de l'adresse (url) de la page de l'événement.
</p>
<a href="{% url 'add_event_url' %}" role="button" class="large">Importer depuis une url</a>
<a href="{% url 'add_event_url' %}" role="button" class="large">Importer un événement depuis son url</a>
<a href="{% url 'add_event_urls' %}" role="button" class="large">Importer des événements depuis leurs urls</a>
<p>Si l'événement n'est pas disponible en ligne, ou si l'import ne fonctionne pas, on peut
ajouter un événement en utilisant un formulaire complet.

View File

@ -4,20 +4,6 @@
{% load static %}
{% block entete_header %}
<script src="{% url 'jsi18n' %}"></script>
<script src="/static/admin/js/vendor/jquery/jquery.js"></script>
<script src="/static/admin/js/jquery.init.js"></script>
<script src="/static/admin/js/admin/DateTimeShortcuts.js"></script>
<script src="{% static 'recurrence/js/recurrence.js' %}"></script>
<script src="/static/admin/js/admin/RelatedObjectLookups.js"></script>
<script src="{% static 'recurrence/js/recurrence-widget.js' %}"></script>
<script src="{% static 'recurrence/js/recurrence-widget.init.js' %}"></script>
<script src="{% static 'js/modal.js' %}"></script>
{% endblock %}
{% block fluid %}{% endblock %}
@ -26,7 +12,7 @@
<article>
<header>
<h1>Importer un événement</h1>
{% url 'event_import_form' as local_url %}
{% url 'event_import_url' as local_url %}
{% include "agenda_culturel/static_content.html" with name="import" url_path=local_url %}
</header>
<div id="container"></div>
@ -34,15 +20,13 @@
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<input type="submit" value="Lancer l'import" id="import-button" data-target="modal-import" onClick="toggleModalNoEscape(event)">
<input type="submit" value="Lancer l'import" id="import-button">
</form>
<p>Si tu as plein d'événements à ajouter, tu peux les <a href="{% url 'add_event_urls' %}" >ajouter par lots</a>.</p>
<p>Si l'import automatique ne marche pas, ou si l'événement n'est pas en ligne, vous pouvez
<p>Si l'import automatique ne marche pas, ou si l'événement n'est pas en ligne, tu peux
tout de même ajouter l'événement en le décrivant sur la page <a href="{% url 'add_event_details' %}" >d'ajout d'événement</a>.</p>
</article>
<dialog id="modal-import">
<article aria-busy="true">
Veuillez patienter, lien en cours d'importation...
</article>
</dialog>
{% endblock %}

View File

@ -0,0 +1,38 @@
{% extends "agenda_culturel/page.html" %}
{% block title %}Importer un ensemble d'événements{% endblock %}
{% load static %}
{% block fluid %}{% endblock %}
{% block content %}
<article>
<header>
<h1>Importer un ensemble d'événements</h1>
{% url 'event_import_urls' as local_url %}
{% include "agenda_culturel/static_content.html" with name="import_set" url_path=local_url %}
</header>
<form method="post">
{{ formset.management_form }}
{% csrf_token %}
{% for form in formset %}
<h2>Nouvel événement #{{ forloop.counter }}</h2>
{{ form.as_p }}
{% endfor %}
<input type="submit" value="Lancer l'import" id="import-button">
</form>
<p>Si l'import automatique ne marche pas, ou si l'événement n'est pas en ligne, vous pouvez
tout de même ajouter l'événement en le décrivant sur la page <a href="{% url 'add_event_details' %}" >d'ajout d'événement</a>.</p>
</article>
<dialog id="modal-import">
<article aria-busy="true">
Veuillez patienter, lien en cours d'importation...
</article>
</dialog>
{% endblock %}

View File

@ -0,0 +1,32 @@
{% extends "agenda_culturel/page.html" %}
{% block title %}Merci !{% endblock %}
{% load static %}
{% block entete_header %}
<script src="{% static 'js/modal.js' %}"></script>
{% endblock %}
{% block fluid %}{% endblock %}
{% block content %}
<article>
<header>
<h1>Merci !</h1>
{% url 'thank_you' as local_url %}
</header>
<div class="grid two-columns-2">
<div class="image"><img src="{% static 'images/merci.svg' %}" alt="quelques pommes et leur pépins" /></div>
<div>
{% include "agenda_culturel/static_content.html" with name="thank-you" url_path=local_url %}
<!-- p>Merci d'avoir ramené ta pomme, et participé à améliorer l'agenda culturel&nbsp;!</p>
<p>N'oublie pas de partager autour de toi les pommes de lune, pour qu'il devienne petit à petit
l'adresse où trouver toutes les activités de Clermont-Ferrand et des environs.</p-->
</div>
</div>
</article>
{% endblock %}

View File

@ -39,6 +39,7 @@ urlpatterns = [
path("event/<int:pk>/moderate", EventModerateView.as_view(), name="moderate_event"),
path("ajouter", import_event_proxy, name="add_event"),
path("ajouter/url", import_from_url, name="add_event_url"),
path("ajouter/urls", import_from_urls, name="add_event_urls"),
path("ajouter/details", EventCreateView.as_view(), name="add_event_details"),
path("admin/", admin.site.urls),
path("accounts/", include("django.contrib.auth.urls")),
@ -57,6 +58,7 @@ urlpatterns = [
path("rechercher/complet/", event_search_full, name="event_search_full"),
path("mentions-legales", mentions_legales, name="mentions_legales"),
path("a-propos", about, name="about"),
path("merci", thank_you, name="thank_you"),
path("contact", ContactMessageCreateView.as_view(), name="contact"),
path("contactmessages", contactmessages, name="contactmessages"),
path(

View File

@ -14,6 +14,8 @@ from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from collections import Counter
from django.forms import formset_factory
from .forms import (
URLSubmissionForm,
EventForm,
@ -46,6 +48,7 @@ from .models import (
Place,
)
from django.utils import timezone
from django.utils.html import escape
from datetime import date, timedelta
from django.db.models import Q
@ -69,6 +72,7 @@ from .celery import (
import_events_from_json,
run_recurrent_import,
run_all_recurrent_imports,
import_events_from_urls,
)
import urllib
@ -122,7 +126,6 @@ to_be_translated = [
_("Recurrent import name"),
_("Add another"),
_("Browse..."),
_("Naviguer..."),
_("No file selected."),
]
@ -141,6 +144,9 @@ def page_not_found(request, exception=None):
def internal_server_error(request):
return render(request, "page-erreur.html", status=500, context={"error": 500})
def thank_you(request):
return render(request, "agenda_culturel/thank_you.html")
class CategoryCheckboxSelectMultiple(forms.CheckboxSelectMultiple):
template_name = "agenda_culturel/forms/category-checkbox.html"
@ -548,155 +554,162 @@ def import_from_details(request):
request, "agenda_culturel/event_form.html", context={"form": form}
)
# A class to evaluate the URL according to the existing events and the authentification
# level of the user
class URLEventEvaluation:
def import_from_url(request):
import logging
def __init__(self, form, is_authenticated):
self.form = form
self.is_authenticated = is_authenticated
logging.getLogger(__name__)
self.cat = None
self.existing = None
self.url = form.cleaned_data.get('url')
self.event = None
if self.url is not None:
self.url = Extractor.clean_url(self.url)
# we check if the url is known
self.existing = Event.objects.filter(uuids__contains=[self.url])
# if it's unknown
if len(self.existing) == 0:
self.existing = None
self.cat = form.cleaned_data.get('category')
if self.cat is not None:
self.cat = self.cat.name
# if a form has been sent and contains an event
if request.method == "POST" and "title" in request.POST:
# the result of this form is checked
form = EventForm(request.POST, is_authenticated=request.user.is_authenticated)
if form.is_valid():
new_event = form.save()
if request.user.is_authenticated:
messages.success(request, _("The event is saved."))
return HttpResponseRedirect(new_event.get_absolute_url())
else:
messages.success(
request,
_(
"The event has been submitted and will be published as soon as it has been validated by the moderation team."
),
)
return HttpResponseRedirect(reverse("home"))
else:
return render(
request, "agenda_culturel/event_form.html", context={"form": form}
)
published = [
e for e in self.existing if e.status == Event.STATUS.PUBLISHED
]
drafts = [e for e in self.existing if e.status == Event.STATUS.DRAFT]
trash = [e for e in self.existing if e.status == Event.STATUS.TRASH]
else:
form = URLSubmissionForm()
initial = {
"start_day": date.today() + timedelta(days=1),
"start_time": "20:00",
"end_time": "22:00",
}
form_event = EventForm(initial=initial)
# if the form has been sent
if request.method == "POST":
form = URLSubmissionForm(request.POST)
# if the form is valid
if form.is_valid():
# the url is cleaned
cd = form.cleaned_data
url = cd.get("url")
url = Extractor.clean_url(url)
# we check if the url is known
existing = Event.objects.filter(uuids__contains=[url])
# if it's unknown
if len(existing) == 0:
event = None
# we import it
logger.warning('on url2event')
u2e = URL2Events(ChromiumHeadlessDownloader(), single_event=True)
events_structure = u2e.process(
url, published=request.user.is_authenticated
)
if (
events_structure is not None
and "events" in events_structure
and len(events_structure["events"]) > 0
):
event = Event.from_structure(
events_structure["events"][0],
events_structure["header"]["url"],
)
# add a category if the user selected one
if event.category is None or event.category == Category.get_default_category():
if cd.get("category") is not None:
event.category = cd.get("category")
# TODO: use celery to import the other events
if event is not None:
event.save()
form = EventForm(
instance=event,
is_authenticated=request.user.is_authenticated,
)
messages.success(
request,
_(
"The event has been successfully extracted, and you can now modify it if necessary."
),
)
return render(
request,
"agenda_culturel/event_form.html",
context={"form": form, "from_import": True},
)
else:
form = EventForm(
initial={"reference_urls": [url]},
is_authenticated=request.user.is_authenticated,
)
messages.error(
request,
_(
"Unable to extract an event from the proposed URL. Please use the form below to submit the event."
),
)
return render(
request,
"agenda_culturel/import.html",
context={"form": form, "form_event": form_event},
)
if self.is_authenticated or len(published) > 1:
self.event = published[0] if len(published) > 1 else self.existing[0]
else:
published = [
e for e in existing if e.status == Event.STATUS.PUBLISHED
]
drafts = [e for e in existing if e.status == Event.STATUS.DRAFT]
trash = [e for e in existing if e.status == Event.STATUS.TRASH]
self.event = None
if request.user.is_authenticated or len(published) > 1:
event = published[0] if len(published) > 1 else existing[0]
def exists(self):
return self.url is not None
def is_new(self):
return self.exists() and self.existing is None
def is_event_visible(self):
if not self.is_new():
return False
return self.event is not None
def get_event(self):
if self.event is None:
return None
else:
return self.event
def get_link(self):
e = self.get_event()
if e is None:
return ""
else:
return '<a href="' + e.get_absolute_url() + '">' + escape(e.title) + '</a>'
def to_list(self):
if self.is_new():
return (self.url, self.cat)
def import_from_urls(request):
URLSubmissionFormSet = formset_factory(URLSubmissionForm, extra=10, min_num=1)
if request.method == "POST":
formset = URLSubmissionFormSet(request.POST, request.FILES)
if formset.is_valid():
# evaluate all the forms
ucat = [URLEventEvaluation(form, request.user.is_authenticated) for form in formset.forms]
# for each not new, add a message
for uc in ucat:
if uc.exists() and not uc.is_new():
if uc.is_event_visible():
messages.info(
request,
_(
"This URL has already been submitted, and you can find the event below."
),
_('{} has not been submitted since it''s already known: {}.').format(uc.url).format(uc.get_link())
)
return HttpResponseRedirect(event.get_absolute_url())
else:
if len(drafts) > 0:
messages.info(
request,
_(
"This URL has already been submitted and is awaiting moderation."
),
)
elif len(trash) > 0:
messages.info(
request,
_(
"This URL has already been submitted, but has not been selected for publication by the moderation team."
),
)
messages.info(
request,
_('{} has not been submitted since it''s already known and currently into moderation process.').format(uc.url)
)
return render(
request,
"agenda_culturel/import.html",
context={"form": form, "form_event": form_event},
)
# keep only new ones
ucat = [uc.to_list() for uc in ucat if uc.is_new()]
# finally process them or go back to home page
if len(ucat) > 0:
logger.warning(ucat)
messages.info(
request,
_('Integrating {} url(s) into our import process.').format(len(ucat))
)
import_events_from_urls.delay(ucat)
return HttpResponseRedirect(reverse("thank_you"))
else:
return HttpResponseRedirect(reverse("home"))
else:
formset = URLSubmissionFormSet()
return render(request, "agenda_culturel/import_set.html", context={"formset": formset})
def import_from_url(request):
form = URLSubmissionForm()
initial = {
"start_day": date.today() + timedelta(days=1),
"start_time": "20:00",
"end_time": "22:00",
}
form_event = EventForm(initial=initial)
# if the form has been sent
if request.method == "POST":
form = URLSubmissionForm(request.POST)
# if the form is valid
if form.is_valid():
uc = URLEventEvaluation(form, request.user.is_authenticated)
if uc.exists() and not uc.is_new():
if uc.is_event_visible():
messages.info(
request,
_('{} has not been submitted since it''s already known: {}.').format(uc.url).format(uc.get_link())
)
return HttpResponseRedirect(uc.get_event().get_absolute_url())
else:
messages.info(
request,
_('{} has not been submitted since it''s already known and currently into moderation process.').format(uc.url)
)
return HttpResponseRedirect(reverse("home"))
else:
messages.info(
request,
_('Integrating {} into our import process.').format(uc.url)
)
import_events_from_urls.delay([uc.to_list()])
return HttpResponseRedirect(reverse("thank_you"))
return render(
request,
"agenda_culturel/import.html",
context={"form": form, "form_event": form_event},
)
def export_event_ical(request, year, month, day, pk):