udata 10.8.1.dev36703__py2.py3-none-any.whl → 10.8.2__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of udata might be problematic. Click here for more details.
- udata/__init__.py +1 -1
- udata/app.py +0 -2
- udata/commands/db.py +22 -9
- udata/core/dataset/models.py +5 -3
- udata/core/discussions/api.py +2 -2
- udata/core/jobs/api.py +3 -3
- udata/core/metrics/helpers.py +10 -0
- udata/core/metrics/tasks.py +144 -1
- udata/core/organization/api.py +2 -2
- udata/core/post/api.py +1 -1
- udata/core/user/api.py +1 -1
- udata/features/identicon/api.py +1 -1
- udata/harvest/actions.py +24 -28
- udata/harvest/api.py +28 -36
- udata/harvest/backends/ckan/__init__.py +3 -0
- udata/harvest/backends/ckan/harvesters.py +274 -0
- udata/harvest/backends/ckan/schemas/__init__.py +0 -0
- udata/harvest/backends/ckan/schemas/ckan.py +86 -0
- udata/harvest/backends/ckan/schemas/dkan.py +98 -0
- udata/harvest/commands.py +7 -7
- udata/harvest/tasks.py +1 -1
- udata/harvest/tests/ckan/conftest.py +67 -0
- udata/harvest/tests/ckan/data/dkan-french-w-license.json +226 -0
- udata/harvest/tests/ckan/test_ckan_backend.py +697 -0
- udata/harvest/tests/ckan/test_ckan_backend_errors.py +140 -0
- udata/harvest/tests/ckan/test_ckan_backend_filters.py +130 -0
- udata/harvest/tests/ckan/test_dkan_backend.py +68 -0
- udata/harvest/tests/test_actions.py +27 -32
- udata/harvest/tests/test_api.py +23 -18
- udata/harvest/tests/test_dcat_backend.py +29 -29
- udata/migrations/2025-07-30-purge-old-harvest-dynamic-fields.py +29 -0
- udata/mongo/slug_fields.py +1 -1
- udata/routing.py +6 -0
- udata/static/chunks/{11.b6f741fcc366abfad9c4.js → 11.51d706fb9521c16976bc.js} +3 -3
- udata/static/chunks/{11.b6f741fcc366abfad9c4.js.map → 11.51d706fb9521c16976bc.js.map} +1 -1
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js → 13.39e106d56f794ebd06a0.js} +2 -2
- udata/static/chunks/{13.2d06442dd9a05d9777b5.js.map → 13.39e106d56f794ebd06a0.js.map} +1 -1
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js → 17.70cbb4a91b002338007e.js} +2 -2
- udata/static/chunks/{17.e8e4caaad5cb0cc0bacc.js.map → 17.70cbb4a91b002338007e.js.map} +1 -1
- udata/static/chunks/{19.f03a102365af4315f9db.js → 19.a348a5fff8fe2801e52a.js} +3 -3
- udata/static/chunks/{19.f03a102365af4315f9db.js.map → 19.a348a5fff8fe2801e52a.js.map} +1 -1
- udata/static/chunks/{5.0fa1408dae4e76b87b2e.js → 5.343ca020a2d38cec1a14.js} +3 -3
- udata/static/chunks/{5.0fa1408dae4e76b87b2e.js.map → 5.343ca020a2d38cec1a14.js.map} +1 -1
- udata/static/chunks/{6.d663709d877baa44a71e.js → 6.a3b07de9dd2ca2d24e85.js} +3 -3
- udata/static/chunks/{6.d663709d877baa44a71e.js.map → 6.a3b07de9dd2ca2d24e85.js.map} +1 -1
- udata/static/chunks/{8.778091d55cd8ea39af6b.js → 8.462bb3029de008497675.js} +2 -2
- udata/static/chunks/{8.778091d55cd8ea39af6b.js.map → 8.462bb3029de008497675.js.map} +1 -1
- udata/static/common.js +1 -1
- udata/static/common.js.map +1 -1
- udata/tests/api/test_datasets_api.py +0 -46
- udata/tests/api/test_organizations_api.py +5 -0
- udata/tests/cli/test_db_cli.py +12 -0
- udata/tests/dataset/test_dataset_model.py +0 -16
- udata/tests/metrics/__init__.py +0 -0
- udata/tests/metrics/conftest.py +15 -0
- udata/tests/metrics/helpers.py +58 -0
- udata/tests/metrics/test_metrics.py +67 -0
- udata/tests/metrics/test_tasks.py +171 -0
- udata/translations/ar/LC_MESSAGES/udata.mo +0 -0
- udata/translations/ar/LC_MESSAGES/udata.po +72 -65
- udata/translations/de/LC_MESSAGES/udata.mo +0 -0
- udata/translations/de/LC_MESSAGES/udata.po +72 -65
- udata/translations/es/LC_MESSAGES/udata.mo +0 -0
- udata/translations/es/LC_MESSAGES/udata.po +72 -65
- udata/translations/fr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/fr/LC_MESSAGES/udata.po +72 -65
- udata/translations/it/LC_MESSAGES/udata.mo +0 -0
- udata/translations/it/LC_MESSAGES/udata.po +72 -65
- udata/translations/pt/LC_MESSAGES/udata.mo +0 -0
- udata/translations/pt/LC_MESSAGES/udata.po +72 -65
- udata/translations/sr/LC_MESSAGES/udata.mo +0 -0
- udata/translations/sr/LC_MESSAGES/udata.po +72 -65
- udata/translations/udata.pot +74 -70
- {udata-10.8.1.dev36703.dist-info → udata-10.8.2.dist-info}/METADATA +15 -2
- {udata-10.8.1.dev36703.dist-info → udata-10.8.2.dist-info}/RECORD +79 -62
- {udata-10.8.1.dev36703.dist-info → udata-10.8.2.dist-info}/entry_points.txt +2 -0
- {udata-10.8.1.dev36703.dist-info → udata-10.8.2.dist-info}/LICENSE +0 -0
- {udata-10.8.1.dev36703.dist-info → udata-10.8.2.dist-info}/WHEEL +0 -0
- {udata-10.8.1.dev36703.dist-info → udata-10.8.2.dist-info}/top_level.txt +0 -0
udata/static/common.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e){function __webpack_require__(c){if(a[c])return a[c].exports;var r=a[c]={exports:{},id:c,loaded:!1};return e[c].call(r.exports,r,r.exports,__webpack_require__),r.loaded=!0,r.exports}var c=window.webpackJsonp;window.webpackJsonp=function(f,d){for(var t,b,_=0,n=[];_<f.length;_++)b=f[_],r[b]&&n.push.apply(n,r[b]),r[b]=0;for(t in d){var i=d[t];switch(typeof i){case"object":e[t]=function(c){var a=c.slice(1),r=c[0];return function(c,f,d){e[r].apply(this,[c,f,d].concat(a))}}(i);break;case"function":e[t]=i;break;default:e[t]=e[i]}}for(c&&c(f,d);n.length;)n.shift().call(null,__webpack_require__);if(d[0])return a[0]=0,__webpack_require__(0)};var a={},r={31:0};__webpack_require__.e=function(e,c){if(0===r[e])return c.call(null,__webpack_require__);if(void 0!==r[e])r[e].push(c);else{r[e]=[c];var a=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.src=__webpack_require__.p+"chunks/"+e+"."+{0:"4dd4f378428d1eed85c8",1:"0a96f54313c89e541ccb",2:"c67aa76cc078c193aed5",3:"174a03e48d267820919b",4:"98dca3045c034c154d5f",5:"
|
|
1
|
+
!function(e){function __webpack_require__(c){if(a[c])return a[c].exports;var r=a[c]={exports:{},id:c,loaded:!1};return e[c].call(r.exports,r,r.exports,__webpack_require__),r.loaded=!0,r.exports}var c=window.webpackJsonp;window.webpackJsonp=function(f,d){for(var t,b,_=0,n=[];_<f.length;_++)b=f[_],r[b]&&n.push.apply(n,r[b]),r[b]=0;for(t in d){var i=d[t];switch(typeof i){case"object":e[t]=function(c){var a=c.slice(1),r=c[0];return function(c,f,d){e[r].apply(this,[c,f,d].concat(a))}}(i);break;case"function":e[t]=i;break;default:e[t]=e[i]}}for(c&&c(f,d);n.length;)n.shift().call(null,__webpack_require__);if(d[0])return a[0]=0,__webpack_require__(0)};var a={},r={31:0};__webpack_require__.e=function(e,c){if(0===r[e])return c.call(null,__webpack_require__);if(void 0!==r[e])r[e].push(c);else{r[e]=[c];var a=document.getElementsByTagName("head")[0],f=document.createElement("script");f.type="text/javascript",f.charset="utf-8",f.async=!0,f.src=__webpack_require__.p+"chunks/"+e+"."+{0:"4dd4f378428d1eed85c8",1:"0a96f54313c89e541ccb",2:"c67aa76cc078c193aed5",3:"174a03e48d267820919b",4:"98dca3045c034c154d5f",5:"343ca020a2d38cec1a14",6:"a3b07de9dd2ca2d24e85",7:"896bbffe39433bb598f7",8:"462bb3029de008497675",9:"033d7e190ca9e226a5d0",10:"8ca60413647062717b1e",11:"51d706fb9521c16976bc",12:"1be61e0201691821bff6",13:"39e106d56f794ebd06a0",14:"bc3f6bc0a67517e7b30f",15:"2f5d8e3d4aa4c46188d7",16:"aaa39ef2d7e82594efc8",17:"70cbb4a91b002338007e",18:"56444ebd2456a4ba2201",19:"a348a5fff8fe2801e52a",20:"3d4e02d1205a3c9e26c5",21:"af1610ce169cf6d1cf4e",22:"6a69068a7dd9d767dea1",23:"663b89b79d755a70deef",24:"d149cf025cbbca231d88",25:"1fafd6424761185cc14b",26:"402064cda3665d56f7fc",27:"997802f273a0c88f7b6d",28:"e68c475c6ca1e2eec92c",29:"2f4a04c61d75f2ef18ab",30:"e97e10c9246818e2b4b2",32:"03cc9867716dd58b9302",33:"011b367beb543774f950"}[e]+".js",a.appendChild(f)}},__webpack_require__.m=e,__webpack_require__.c=a,__webpack_require__.p="/static/"}(function(e){for(var c in e)if(Object.prototype.hasOwnProperty.call(e,c))switch(typeof e[c]){case"function":break;case"object":e[c]=function(c){var a=c.slice(1),r=e[c[0]];return function(e,c,f){r.apply(this,[e,c,f].concat(a))}}(e[c]);break;default:e[c]=e[e[c]]}return e}([]));
|
|
2
2
|
//# sourceMappingURL=common.js.map
|
udata/static/common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["webpack:///common.js","webpack:///webpack/bootstrap 44a61f162b1337addb9e"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","parentJsonpFunction","window","chunkIds","moreModules","chunkId","i","callbacks","length","installedChunks","push","apply","_m","args","slice","templateId","a","b","c","this","concat","shift","31","e","callback","undefined","head","document","getElementsByTagName","script","createElement","type","charset","async","src","p","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","32","33","appendChild","m","Object","prototype","hasOwnProperty","fn"],"mappings":"CAAS,SAAUA,GCwDnB,QAAAC,qBAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,qBAGAI,EAAAE,QAAA,EAGAF,EAAAD,QA3EA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAA,EAAAC,KACQD,EAAAH,EAAAK,OAAoBF,IAC5BD,EAAAF,EAAAG,GACAG,EAAAJ,IACAE,EAAAG,KAAAC,MAAAJ,EAAAE,EAAAJ,IACAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAU,GAAA,CACA,GAAAQ,GAAAR,EAAAV,EAGA,cAAAkB,IACA,aAEApB,EAAAE,GAAA,SAAAkB,GACA,GAAAC,GAAAD,EAAAE,MAAA,GAAAC,EAAAH,EAAA,EACA,iBAAAI,EAAAC,EAAAC,GACA1B,EAAAuB,GAAAJ,MAAAQ,MAAAH,EAAAC,EAAAC,GAAAE,OAAAP,MAEMD,EACN,MACA,gBAEApB,EAAAE,GAAAkB,CACA,MACA,SAEApB,EAAAE,GAAAF,EAAAoB,IAKA,IADAX,KAAAE,EAAAC,GACAG,EAAAC,QACAD,EAAAc,QAAArB,KAAA,KAAAP,oBACA,IAAAW,EAAA,GAEA,MADAT,GAAA,KACAF,oBAAA,GAKA,IAAAE,MAKAc,GACAa,GAAA,EA6BA7B,qBAAA8B,EAAA,SAAAlB,EAAAmB,GAEA,OAAAf,EAAAJ,GACA,MAAAmB,GAAAxB,KAAA,KAAAP,oBAGA,IAAAgC,SAAAhB,EAAAJ,GACAI,EAAAJ,GAAAK,KAAAc,OACI,CAEJf,EAAAJ,IAAAmB,EACA,IAAAE,GAAAC,SAAAC,qBAAA,WACAC,EAAAF,SAAAG,cAAA,SACAD,GAAAE,KAAA,kBACAF,EAAAG,QAAA,QACAH,EAAAI,OAAA,EAEAJ,EAAAK,IAAAzC,oBAAA0C,EAAA,UAAA9B,EAAA,KAAsE+B,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,wBAAk5B/D,GAAA,MACx9BqB,EAAA2C,YAAAxC,KAKApC,oBAAA6E,EAAA9E,EAGAC,oBAAAyB,EAAAvB,EAGAF,oBAAA0C,EAAA,YDIW,SAAS3C,GAEnB,IAAI,GAAIc,KAAKd,GACZ,GAAG+E,OAAOC,UAAUC,eAAezE,KAAKR,EAASc,GAChD,aAAcd,GAAQc,IACtB,IAAK,WAAY,KACjB,KAAK,SAEJd,EAAQc,GAAM,SAASM,GACtB,GAAIC,GAAOD,EAAGE,MAAM,GAAI4D,EAAKlF,EAAQoB,EAAG,GACxC,OAAO,UAAUI,EAAEC,EAAEC,GACpBwD,EAAG/D,MAAMQ,MAAOH,EAAEC,EAAEC,GAAGE,OAAOP,MAE9BrB,EAAQc,GACV,MACD,SAECd,EAAQc,GAAKd,EAAQA,EAAQc,IAKhC,MAAOd","file":"common.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId])\n/******/ \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tvar _m = moreModules[moduleId];\n/******/\n/******/ \t\t\t// Check if module is deduplicated\n/******/ \t\t\tswitch(typeof _m) {\n/******/ \t\t\tcase \"object\":\n/******/ \t\t\t\t// Module can be created from a template\n/******/ \t\t\t\tmodules[moduleId] = (function(_m) {\n/******/ \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n/******/ \t\t\t\t\treturn function (a,b,c) {\n/******/ \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n/******/ \t\t\t\t\t};\n/******/ \t\t\t\t}(_m));\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tcase \"function\":\n/******/ \t\t\t\t// Normal module\n/******/ \t\t\t\tmodules[moduleId] = _m;\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tdefault:\n/******/ \t\t\t\t// Module is a copy of another module\n/******/ \t\t\t\tmodules[moduleId] = modules[_m];\n/******/ \t\t\t\tbreak;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n/******/ \t\twhile(callbacks.length)\n/******/ \t\t\tcallbacks.shift().call(null, __webpack_require__);\n/******/ \t\tif(moreModules[0]) {\n/******/ \t\t\tinstalledModules[0] = 0;\n/******/ \t\t\treturn __webpack_require__(0);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// object to store loaded and loading chunks\n/******/ \t// \"0\" means \"already loaded\"\n/******/ \t// Array means \"loading\", array contains callbacks\n/******/ \tvar installedChunks = {\n/******/ \t\t31:0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n/******/ \t\t// \"0\" is the signal for \"already loaded\"\n/******/ \t\tif(installedChunks[chunkId] === 0)\n/******/ \t\t\treturn callback.call(null, __webpack_require__);\n/******/\n/******/ \t\t// an array means \"currently loading\".\n/******/ \t\tif(installedChunks[chunkId] !== undefined) {\n/******/ \t\t\tinstalledChunks[chunkId].push(callback);\n/******/ \t\t} else {\n/******/ \t\t\t// start chunk loading\n/******/ \t\t\tinstalledChunks[chunkId] = [callback];\n/******/ \t\t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\t\tvar script = document.createElement('script');\n/******/ \t\t\tscript.type = 'text/javascript';\n/******/ \t\t\tscript.charset = 'utf-8';\n/******/ \t\t\tscript.async = true;\n/******/\n/******/ \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"0fa1408dae4e76b87b2e\",\"6\":\"d663709d877baa44a71e\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"778091d55cd8ea39af6b\",\"9\":\"033d7e190ca9e226a5d0\",\"10\":\"8ca60413647062717b1e\",\"11\":\"b6f741fcc366abfad9c4\",\"12\":\"1be61e0201691821bff6\",\"13\":\"2d06442dd9a05d9777b5\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"e8e4caaad5cb0cc0bacc\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"f03a102365af4315f9db\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"03cc9867716dd58b9302\",\"33\":\"011b367beb543774f950\"}[chunkId] + \".js\";\n/******/ \t\t\thead.appendChild(script);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/static/\";\n/******/ })\n/************************************************************************/\n/******/ ((function(modules) {\n\t// Check all modules for deduplicated modules\n\tfor(var i in modules) {\n\t\tif(Object.prototype.hasOwnProperty.call(modules, i)) {\n\t\t\tswitch(typeof modules[i]) {\n\t\t\tcase \"function\": break;\n\t\t\tcase \"object\":\n\t\t\t\t// Module can be created from a template\n\t\t\t\tmodules[i] = (function(_m) {\n\t\t\t\t\tvar args = _m.slice(1), fn = modules[_m[0]];\n\t\t\t\t\treturn function (a,b,c) {\n\t\t\t\t\t\tfn.apply(this, [a,b,c].concat(args));\n\t\t\t\t\t};\n\t\t\t\t}(modules[i]));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Module is a copy of another module\n\t\t\t\tmodules[i] = modules[modules[i]];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn modules;\n}([])));\n\n\n/** WEBPACK FOOTER **\n ** common.js\n **/"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tvar _m = moreModules[moduleId];\n\n \t\t\t// Check if module is deduplicated\n \t\t\tswitch(typeof _m) {\n \t\t\tcase \"object\":\n \t\t\t\t// Module can be created from a template\n \t\t\t\tmodules[moduleId] = (function(_m) {\n \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n \t\t\t\t\treturn function (a,b,c) {\n \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n \t\t\t\t\t};\n \t\t\t\t}(_m));\n \t\t\t\tbreak;\n \t\t\tcase \"function\":\n \t\t\t\t// Normal module\n \t\t\t\tmodules[moduleId] = _m;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\t// Module is a copy of another module\n \t\t\t\tmodules[moduleId] = modules[_m];\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t31:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"0fa1408dae4e76b87b2e\",\"6\":\"d663709d877baa44a71e\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"778091d55cd8ea39af6b\",\"9\":\"033d7e190ca9e226a5d0\",\"10\":\"8ca60413647062717b1e\",\"11\":\"b6f741fcc366abfad9c4\",\"12\":\"1be61e0201691821bff6\",\"13\":\"2d06442dd9a05d9777b5\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"e8e4caaad5cb0cc0bacc\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"f03a102365af4315f9db\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"03cc9867716dd58b9302\",\"33\":\"011b367beb543774f950\"}[chunkId] + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 44a61f162b1337addb9e\n **/"],"sourceRoot":""}
|
|
1
|
+
{"version":3,"sources":["webpack:///common.js","webpack:///webpack/bootstrap 3bb9132a729303a06045"],"names":["modules","__webpack_require__","moduleId","installedModules","exports","module","id","loaded","call","parentJsonpFunction","window","chunkIds","moreModules","chunkId","i","callbacks","length","installedChunks","push","apply","_m","args","slice","templateId","a","b","c","this","concat","shift","31","e","callback","undefined","head","document","getElementsByTagName","script","createElement","type","charset","async","src","p","0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","32","33","appendChild","m","Object","prototype","hasOwnProperty","fn"],"mappings":"CAAS,SAAUA,GCwDnB,QAAAC,qBAAAC,GAGA,GAAAC,EAAAD,GACA,MAAAC,GAAAD,GAAAE,OAGA,IAAAC,GAAAF,EAAAD,IACAE,WACAE,GAAAJ,EACAK,QAAA,EAUA,OANAP,GAAAE,GAAAM,KAAAH,EAAAD,QAAAC,IAAAD,QAAAH,qBAGAI,EAAAE,QAAA,EAGAF,EAAAD,QA3EA,GAAAK,GAAAC,OAAA,YACAA,QAAA,sBAAAC,EAAAC,GAIA,IADA,GAAAV,GAAAW,EAAAC,EAAA,EAAAC,KACQD,EAAAH,EAAAK,OAAoBF,IAC5BD,EAAAF,EAAAG,GACAG,EAAAJ,IACAE,EAAAG,KAAAC,MAAAJ,EAAAE,EAAAJ,IACAI,EAAAJ,GAAA,CAEA,KAAAX,IAAAU,GAAA,CACA,GAAAQ,GAAAR,EAAAV,EAGA,cAAAkB,IACA,aAEApB,EAAAE,GAAA,SAAAkB,GACA,GAAAC,GAAAD,EAAAE,MAAA,GAAAC,EAAAH,EAAA,EACA,iBAAAI,EAAAC,EAAAC,GACA1B,EAAAuB,GAAAJ,MAAAQ,MAAAH,EAAAC,EAAAC,GAAAE,OAAAP,MAEMD,EACN,MACA,gBAEApB,EAAAE,GAAAkB,CACA,MACA,SAEApB,EAAAE,GAAAF,EAAAoB,IAKA,IADAX,KAAAE,EAAAC,GACAG,EAAAC,QACAD,EAAAc,QAAArB,KAAA,KAAAP,oBACA,IAAAW,EAAA,GAEA,MADAT,GAAA,KACAF,oBAAA,GAKA,IAAAE,MAKAc,GACAa,GAAA,EA6BA7B,qBAAA8B,EAAA,SAAAlB,EAAAmB,GAEA,OAAAf,EAAAJ,GACA,MAAAmB,GAAAxB,KAAA,KAAAP,oBAGA,IAAAgC,SAAAhB,EAAAJ,GACAI,EAAAJ,GAAAK,KAAAc,OACI,CAEJf,EAAAJ,IAAAmB,EACA,IAAAE,GAAAC,SAAAC,qBAAA,WACAC,EAAAF,SAAAG,cAAA,SACAD,GAAAE,KAAA,kBACAF,EAAAG,QAAA,QACAH,EAAAI,OAAA,EAEAJ,EAAAK,IAAAzC,oBAAA0C,EAAA,UAAA9B,EAAA,KAAsE+B,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,EAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,uBAAAC,GAAA,wBAAk5B/D,GAAA,MACx9BqB,EAAA2C,YAAAxC,KAKApC,oBAAA6E,EAAA9E,EAGAC,oBAAAyB,EAAAvB,EAGAF,oBAAA0C,EAAA,YDIW,SAAS3C,GAEnB,IAAI,GAAIc,KAAKd,GACZ,GAAG+E,OAAOC,UAAUC,eAAezE,KAAKR,EAASc,GAChD,aAAcd,GAAQc,IACtB,IAAK,WAAY,KACjB,KAAK,SAEJd,EAAQc,GAAM,SAASM,GACtB,GAAIC,GAAOD,EAAGE,MAAM,GAAI4D,EAAKlF,EAAQoB,EAAG,GACxC,OAAO,UAAUI,EAAEC,EAAEC,GACpBwD,EAAG/D,MAAMQ,MAAOH,EAAEC,EAAEC,GAAGE,OAAOP,MAE9BrB,EAAQc,GACV,MACD,SAECd,EAAQc,GAAKd,EAAQA,EAAQc,IAKhC,MAAOd","file":"common.js","sourcesContent":["/******/ (function(modules) { // webpackBootstrap\n/******/ \t// install a JSONP callback for chunk loading\n/******/ \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n/******/ \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n/******/ \t\t// add \"moreModules\" to the modules object,\n/******/ \t\t// then flag all \"chunkIds\" as loaded and fire callback\n/******/ \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n/******/ \t\tfor(;i < chunkIds.length; i++) {\n/******/ \t\t\tchunkId = chunkIds[i];\n/******/ \t\t\tif(installedChunks[chunkId])\n/******/ \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n/******/ \t\t\tinstalledChunks[chunkId] = 0;\n/******/ \t\t}\n/******/ \t\tfor(moduleId in moreModules) {\n/******/ \t\t\tvar _m = moreModules[moduleId];\n/******/\n/******/ \t\t\t// Check if module is deduplicated\n/******/ \t\t\tswitch(typeof _m) {\n/******/ \t\t\tcase \"object\":\n/******/ \t\t\t\t// Module can be created from a template\n/******/ \t\t\t\tmodules[moduleId] = (function(_m) {\n/******/ \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n/******/ \t\t\t\t\treturn function (a,b,c) {\n/******/ \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n/******/ \t\t\t\t\t};\n/******/ \t\t\t\t}(_m));\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tcase \"function\":\n/******/ \t\t\t\t// Normal module\n/******/ \t\t\t\tmodules[moduleId] = _m;\n/******/ \t\t\t\tbreak;\n/******/ \t\t\tdefault:\n/******/ \t\t\t\t// Module is a copy of another module\n/******/ \t\t\t\tmodules[moduleId] = modules[_m];\n/******/ \t\t\t\tbreak;\n/******/ \t\t\t}\n/******/ \t\t}\n/******/ \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n/******/ \t\twhile(callbacks.length)\n/******/ \t\t\tcallbacks.shift().call(null, __webpack_require__);\n/******/ \t\tif(moreModules[0]) {\n/******/ \t\t\tinstalledModules[0] = 0;\n/******/ \t\t\treturn __webpack_require__(0);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// object to store loaded and loading chunks\n/******/ \t// \"0\" means \"already loaded\"\n/******/ \t// Array means \"loading\", array contains callbacks\n/******/ \tvar installedChunks = {\n/******/ \t\t31:0\n/******/ \t};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/ \t// This file contains only the entry chunk.\n/******/ \t// The chunk loading function for additional chunks\n/******/ \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n/******/ \t\t// \"0\" is the signal for \"already loaded\"\n/******/ \t\tif(installedChunks[chunkId] === 0)\n/******/ \t\t\treturn callback.call(null, __webpack_require__);\n/******/\n/******/ \t\t// an array means \"currently loading\".\n/******/ \t\tif(installedChunks[chunkId] !== undefined) {\n/******/ \t\t\tinstalledChunks[chunkId].push(callback);\n/******/ \t\t} else {\n/******/ \t\t\t// start chunk loading\n/******/ \t\t\tinstalledChunks[chunkId] = [callback];\n/******/ \t\t\tvar head = document.getElementsByTagName('head')[0];\n/******/ \t\t\tvar script = document.createElement('script');\n/******/ \t\t\tscript.type = 'text/javascript';\n/******/ \t\t\tscript.charset = 'utf-8';\n/******/ \t\t\tscript.async = true;\n/******/\n/******/ \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"343ca020a2d38cec1a14\",\"6\":\"a3b07de9dd2ca2d24e85\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"462bb3029de008497675\",\"9\":\"033d7e190ca9e226a5d0\",\"10\":\"8ca60413647062717b1e\",\"11\":\"51d706fb9521c16976bc\",\"12\":\"1be61e0201691821bff6\",\"13\":\"39e106d56f794ebd06a0\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"70cbb4a91b002338007e\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"a348a5fff8fe2801e52a\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"03cc9867716dd58b9302\",\"33\":\"011b367beb543774f950\"}[chunkId] + \".js\";\n/******/ \t\t\thead.appendChild(script);\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"/static/\";\n/******/ })\n/************************************************************************/\n/******/ ((function(modules) {\n\t// Check all modules for deduplicated modules\n\tfor(var i in modules) {\n\t\tif(Object.prototype.hasOwnProperty.call(modules, i)) {\n\t\t\tswitch(typeof modules[i]) {\n\t\t\tcase \"function\": break;\n\t\t\tcase \"object\":\n\t\t\t\t// Module can be created from a template\n\t\t\t\tmodules[i] = (function(_m) {\n\t\t\t\t\tvar args = _m.slice(1), fn = modules[_m[0]];\n\t\t\t\t\treturn function (a,b,c) {\n\t\t\t\t\t\tfn.apply(this, [a,b,c].concat(args));\n\t\t\t\t\t};\n\t\t\t\t}(modules[i]));\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// Module is a copy of another module\n\t\t\t\tmodules[i] = modules[modules[i]];\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn modules;\n}([])));\n\n\n/** WEBPACK FOOTER **\n ** common.js\n **/"," \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, callbacks = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tcallbacks.push.apply(callbacks, installedChunks[chunkId]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tvar _m = moreModules[moduleId];\n\n \t\t\t// Check if module is deduplicated\n \t\t\tswitch(typeof _m) {\n \t\t\tcase \"object\":\n \t\t\t\t// Module can be created from a template\n \t\t\t\tmodules[moduleId] = (function(_m) {\n \t\t\t\t\tvar args = _m.slice(1), templateId = _m[0];\n \t\t\t\t\treturn function (a,b,c) {\n \t\t\t\t\t\tmodules[templateId].apply(this, [a,b,c].concat(args));\n \t\t\t\t\t};\n \t\t\t\t}(_m));\n \t\t\t\tbreak;\n \t\t\tcase \"function\":\n \t\t\t\t// Normal module\n \t\t\t\tmodules[moduleId] = _m;\n \t\t\t\tbreak;\n \t\t\tdefault:\n \t\t\t\t// Module is a copy of another module\n \t\t\t\tmodules[moduleId] = modules[_m];\n \t\t\t\tbreak;\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules);\n \t\twhile(callbacks.length)\n \t\t\tcallbacks.shift().call(null, __webpack_require__);\n \t\tif(moreModules[0]) {\n \t\t\tinstalledModules[0] = 0;\n \t\t\treturn __webpack_require__(0);\n \t\t}\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// \"0\" means \"already loaded\"\n \t// Array means \"loading\", array contains callbacks\n \tvar installedChunks = {\n \t\t31:0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId, callback) {\n \t\t// \"0\" is the signal for \"already loaded\"\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn callback.call(null, __webpack_require__);\n\n \t\t// an array means \"currently loading\".\n \t\tif(installedChunks[chunkId] !== undefined) {\n \t\t\tinstalledChunks[chunkId].push(callback);\n \t\t} else {\n \t\t\t// start chunk loading\n \t\t\tinstalledChunks[chunkId] = [callback];\n \t\t\tvar head = document.getElementsByTagName('head')[0];\n \t\t\tvar script = document.createElement('script');\n \t\t\tscript.type = 'text/javascript';\n \t\t\tscript.charset = 'utf-8';\n \t\t\tscript.async = true;\n\n \t\t\tscript.src = __webpack_require__.p + \"chunks/\" + chunkId + \".\" + {\"0\":\"4dd4f378428d1eed85c8\",\"1\":\"0a96f54313c89e541ccb\",\"2\":\"c67aa76cc078c193aed5\",\"3\":\"174a03e48d267820919b\",\"4\":\"98dca3045c034c154d5f\",\"5\":\"343ca020a2d38cec1a14\",\"6\":\"a3b07de9dd2ca2d24e85\",\"7\":\"896bbffe39433bb598f7\",\"8\":\"462bb3029de008497675\",\"9\":\"033d7e190ca9e226a5d0\",\"10\":\"8ca60413647062717b1e\",\"11\":\"51d706fb9521c16976bc\",\"12\":\"1be61e0201691821bff6\",\"13\":\"39e106d56f794ebd06a0\",\"14\":\"bc3f6bc0a67517e7b30f\",\"15\":\"2f5d8e3d4aa4c46188d7\",\"16\":\"aaa39ef2d7e82594efc8\",\"17\":\"70cbb4a91b002338007e\",\"18\":\"56444ebd2456a4ba2201\",\"19\":\"a348a5fff8fe2801e52a\",\"20\":\"3d4e02d1205a3c9e26c5\",\"21\":\"af1610ce169cf6d1cf4e\",\"22\":\"6a69068a7dd9d767dea1\",\"23\":\"663b89b79d755a70deef\",\"24\":\"d149cf025cbbca231d88\",\"25\":\"1fafd6424761185cc14b\",\"26\":\"402064cda3665d56f7fc\",\"27\":\"997802f273a0c88f7b6d\",\"28\":\"e68c475c6ca1e2eec92c\",\"29\":\"2f4a04c61d75f2ef18ab\",\"30\":\"e97e10c9246818e2b4b2\",\"32\":\"03cc9867716dd58b9302\",\"33\":\"011b367beb543774f950\"}[chunkId] + \".js\";\n \t\t\thead.appendChild(script);\n \t\t}\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 3bb9132a729303a06045\n **/"],"sourceRoot":""}
|
|
@@ -15,10 +15,6 @@ from udata.api import fields
|
|
|
15
15
|
from udata.app import cache
|
|
16
16
|
from udata.core import storages
|
|
17
17
|
from udata.core.badges.factories import badge_factory
|
|
18
|
-
from udata.core.dataset.api_fields import (
|
|
19
|
-
dataset_harvest_fields,
|
|
20
|
-
resource_harvest_fields,
|
|
21
|
-
)
|
|
22
18
|
from udata.core.dataset.constants import (
|
|
23
19
|
DEFAULT_FREQUENCY,
|
|
24
20
|
DEFAULT_LICENSE,
|
|
@@ -2391,10 +2387,6 @@ class DatasetSchemasAPITest:
|
|
|
2391
2387
|
class HarvestMetadataAPITest:
|
|
2392
2388
|
modules = []
|
|
2393
2389
|
|
|
2394
|
-
# api fields should be updated before app is created
|
|
2395
|
-
dataset_harvest_fields["dynamic_field"] = fields.String(description="", allow_null=True)
|
|
2396
|
-
resource_harvest_fields["dynamic_field"] = fields.String(description="", allow_null=True)
|
|
2397
|
-
|
|
2398
2390
|
def test_dataset_with_harvest_metadata(self, api):
|
|
2399
2391
|
date = datetime(2022, 2, 22, tzinfo=pytz.UTC)
|
|
2400
2392
|
harvest_metadata = HarvestDatasetMetadata(
|
|
@@ -2430,24 +2422,6 @@ class HarvestMetadataAPITest:
|
|
|
2430
2422
|
"archived": "not-on-remote",
|
|
2431
2423
|
}
|
|
2432
2424
|
|
|
2433
|
-
def test_dataset_dynamic_harvest_metadata_without_api_field(self, api):
|
|
2434
|
-
harvest_metadata = HarvestDatasetMetadata(dynamic_field_but_no_api_field_defined="DCAT")
|
|
2435
|
-
dataset = DatasetFactory(harvest=harvest_metadata)
|
|
2436
|
-
|
|
2437
|
-
response = api.get(url_for("api.dataset", dataset=dataset))
|
|
2438
|
-
assert200(response)
|
|
2439
|
-
assert response.json["harvest"] == {}
|
|
2440
|
-
|
|
2441
|
-
def test_dataset_dynamic_harvest_metadata_with_api_field(self, api):
|
|
2442
|
-
harvest_metadata = HarvestDatasetMetadata(dynamic_field="dynamic_value")
|
|
2443
|
-
dataset = DatasetFactory(harvest=harvest_metadata)
|
|
2444
|
-
|
|
2445
|
-
response = api.get(url_for("api.dataset", dataset=dataset))
|
|
2446
|
-
assert200(response)
|
|
2447
|
-
assert response.json["harvest"] == {
|
|
2448
|
-
"dynamic_field": "dynamic_value",
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
2425
|
def test_dataset_with_resource_harvest_metadata(self, api):
|
|
2452
2426
|
date = datetime(2022, 2, 22, tzinfo=pytz.UTC)
|
|
2453
2427
|
|
|
@@ -2466,26 +2440,6 @@ class HarvestMetadataAPITest:
|
|
|
2466
2440
|
"uri": "http://domain.gouv.fr/dataset/uri",
|
|
2467
2441
|
}
|
|
2468
2442
|
|
|
2469
|
-
def test_resource_dynamic_harvest_metadata_without_api_field(self, api):
|
|
2470
|
-
harvest_metadata = HarvestResourceMetadata(
|
|
2471
|
-
dynamic_field_but_no_api_field_defined="dynamic_value"
|
|
2472
|
-
)
|
|
2473
|
-
dataset = DatasetFactory(resources=[ResourceFactory(harvest=harvest_metadata)])
|
|
2474
|
-
|
|
2475
|
-
response = api.get(url_for("api.dataset", dataset=dataset))
|
|
2476
|
-
assert200(response)
|
|
2477
|
-
assert response.json["resources"][0]["harvest"] == {}
|
|
2478
|
-
|
|
2479
|
-
def test_resource_dynamic_harvest_metadata_with_api_field(self, api):
|
|
2480
|
-
harvest_metadata = HarvestResourceMetadata(dynamic_field="dynamic_value")
|
|
2481
|
-
dataset = DatasetFactory(resources=[ResourceFactory(harvest=harvest_metadata)])
|
|
2482
|
-
|
|
2483
|
-
response = api.get(url_for("api.dataset", dataset=dataset))
|
|
2484
|
-
assert200(response)
|
|
2485
|
-
assert response.json["resources"][0]["harvest"] == {
|
|
2486
|
-
"dynamic_field": "dynamic_value",
|
|
2487
|
-
}
|
|
2488
|
-
|
|
2489
2443
|
def test_dataset_with_harvest_computed_dates(self, api):
|
|
2490
2444
|
creation_date = datetime(2022, 2, 22, tzinfo=pytz.UTC)
|
|
2491
2445
|
modification_date = datetime(2022, 3, 19, tzinfo=pytz.UTC)
|
|
@@ -68,6 +68,11 @@ class OrganizationAPITest:
|
|
|
68
68
|
assert len(response.json["data"]) == 1
|
|
69
69
|
assert response.json["data"][0]["id"] == str(org.id)
|
|
70
70
|
|
|
71
|
+
response = api.get(url_for("api.organizations", name=org.name.upper()))
|
|
72
|
+
assert200(response)
|
|
73
|
+
assert len(response.json["data"]) == 1
|
|
74
|
+
assert response.json["data"][0]["id"] == str(org.id)
|
|
75
|
+
|
|
71
76
|
response = api.get(url_for("api.organizations", name="Some other name"))
|
|
72
77
|
assert200(response)
|
|
73
78
|
assert len(response.json["data"]) == 0
|
udata/tests/cli/test_db_cli.py
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
|
|
3
3
|
import pytest
|
|
4
|
+
from bson import ObjectId
|
|
5
|
+
|
|
6
|
+
from udata.models import Reuse
|
|
4
7
|
|
|
5
8
|
|
|
6
9
|
@pytest.fixture
|
|
@@ -57,3 +60,12 @@ def test_unrecord_with_too_many_parameters(cli, migrations):
|
|
|
57
60
|
result = cli("db unrecord udata test.py too many", check=False)
|
|
58
61
|
assert result.exit_code != 0
|
|
59
62
|
assert migrations.count_documents({}) == 1
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_check_references_report_listfield_missing(cli, clean_db):
|
|
66
|
+
# The cli command `udata db check-integrity` should catch reuse object missing datasets field
|
|
67
|
+
Reuse._get_collection().insert_one({"_id": ObjectId()})
|
|
68
|
+
|
|
69
|
+
result = cli("db check-integrity --models Reuse", check=False)
|
|
70
|
+
assert "Reuse.datasets(Dataset) — list…: 1" in result.output
|
|
71
|
+
assert result.exit_code != 0
|
|
@@ -789,14 +789,6 @@ class HarvestMetadataTest:
|
|
|
789
789
|
with pytest.raises(db.ValidationError):
|
|
790
790
|
dataset.save()
|
|
791
791
|
|
|
792
|
-
def test_harvest_dataset_metadata_no_validation_dynamic(self):
|
|
793
|
-
# Adding a dynamic field (not defined in HarvestDatasetMetadata) does not raise error
|
|
794
|
-
# at validation time
|
|
795
|
-
harvest_metadata = HarvestDatasetMetadata(dynamic_created_at="maintenant")
|
|
796
|
-
dataset = DatasetFactory()
|
|
797
|
-
dataset.harvest = harvest_metadata
|
|
798
|
-
dataset.save()
|
|
799
|
-
|
|
800
792
|
def test_harvest_dataset_metadata_past_modifed_at(self):
|
|
801
793
|
dataset = DatasetFactory()
|
|
802
794
|
|
|
@@ -826,14 +818,6 @@ class HarvestMetadataTest:
|
|
|
826
818
|
with pytest.raises(db.ValidationError):
|
|
827
819
|
resource.validate()
|
|
828
820
|
|
|
829
|
-
def test_harvest_resource_metadata_no_validation_dynamic(self):
|
|
830
|
-
# Adding a dynamic field (not defined in HarvestResourceMetadata) does not raise error
|
|
831
|
-
# at validation time
|
|
832
|
-
harvest_metadata = HarvestResourceMetadata(dynamic_created_at="maintenant")
|
|
833
|
-
resource = ResourceFactory()
|
|
834
|
-
resource.harvest = harvest_metadata
|
|
835
|
-
resource.validate()
|
|
836
|
-
|
|
837
821
|
def test_harvest_resource_metadata_future_modifed_at(self):
|
|
838
822
|
resource = ResourceFactory()
|
|
839
823
|
harvest_metadata = HarvestResourceMetadata(
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from udata import settings
|
|
4
|
+
from udata.app import create_app
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MetricsSettings(settings.Testing):
|
|
8
|
+
PLUGINS = ["metrics"]
|
|
9
|
+
METRICS_API = "http://metrics-api.fr/api"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.fixture
|
|
13
|
+
def app():
|
|
14
|
+
app = create_app(settings.Defaults, override=MetricsSettings)
|
|
15
|
+
return app
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def chunks(xs, n):
|
|
5
|
+
return [xs[i : i + n] for i in range(0, len(xs), n)]
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def mock_metrics_api(app, rmock, endpoint, value_keys, values, page_size: int = 50):
|
|
9
|
+
for i, value in enumerate(values):
|
|
10
|
+
value["__id"] = i
|
|
11
|
+
|
|
12
|
+
chunked = list(chunks(values, page_size))
|
|
13
|
+
|
|
14
|
+
for value_key in value_keys:
|
|
15
|
+
next = None
|
|
16
|
+
for i, chunk in enumerate(chunked):
|
|
17
|
+
page_number = i + 1
|
|
18
|
+
|
|
19
|
+
if next is None:
|
|
20
|
+
url = f"{app.config['METRICS_API']}/{endpoint}_total/data/?{value_key}__greater=1&page_size={page_size}"
|
|
21
|
+
else:
|
|
22
|
+
url = next
|
|
23
|
+
|
|
24
|
+
# Test if we're on the last page
|
|
25
|
+
if page_number == len(chunked):
|
|
26
|
+
next = None
|
|
27
|
+
else:
|
|
28
|
+
next = f"{app.config['METRICS_API']}/{endpoint}_total/data/?{value_key}__greater=1&page={page_number + 1}&page_size={page_size}"
|
|
29
|
+
|
|
30
|
+
rmock.get(
|
|
31
|
+
url, json={"data": chunk, "links": {"next": next}, "meta": {"total": len(values)}}
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def mock_monthly_metrics_payload(app, rmock, target, data, target_id="id", url=None):
|
|
36
|
+
if not url:
|
|
37
|
+
url = (
|
|
38
|
+
f"{app.config['METRICS_API']}/{target}s/data/"
|
|
39
|
+
+ f"?metric_month__sort=desc&{target}_id__exact={target_id}"
|
|
40
|
+
)
|
|
41
|
+
current_month = datetime.now().strftime("%Y-%m")
|
|
42
|
+
last_month = (datetime.now().replace(day=1) - timedelta(days=1)).strftime("%Y-%m")
|
|
43
|
+
rmock.get(
|
|
44
|
+
url,
|
|
45
|
+
json={
|
|
46
|
+
"data": [
|
|
47
|
+
{
|
|
48
|
+
"metric_month": current_month,
|
|
49
|
+
**{f"monthly_{key}": len(key) * value + 1 for key, value in data},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"metric_month": last_month,
|
|
53
|
+
**{f"monthly_{key}": len(key) * value for key, value in data},
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
"meta": {"total": 2},
|
|
57
|
+
},
|
|
58
|
+
)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
|
|
5
|
+
from udata.core.dataservices.factories import DataserviceFactory
|
|
6
|
+
from udata.core.dataservices.models import Dataservice
|
|
7
|
+
from udata.core.dataset.factories import DatasetFactory
|
|
8
|
+
from udata.core.metrics.helpers import get_metrics_for_model, get_stock_metrics
|
|
9
|
+
from udata.core.organization.factories import OrganizationFactory
|
|
10
|
+
from udata.core.reuse.factories import ReuseFactory
|
|
11
|
+
from udata.models import Dataset, Organization, Reuse
|
|
12
|
+
|
|
13
|
+
from .helpers import mock_monthly_metrics_payload
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@pytest.mark.parametrize(
|
|
17
|
+
"target,value_keys",
|
|
18
|
+
[
|
|
19
|
+
("dataset", ["visit", "download_resource"]),
|
|
20
|
+
("dataservice", ["visit"]),
|
|
21
|
+
("reuse", ["visit"]),
|
|
22
|
+
("organization", ["visit_dataset", "download_resource", "visit_reuse"]),
|
|
23
|
+
],
|
|
24
|
+
)
|
|
25
|
+
def test_get_metrics_for_model(app, rmock, target, value_keys):
|
|
26
|
+
mock_monthly_metrics_payload(
|
|
27
|
+
app, rmock, target, data=[(value_key, 2403) for value_key in value_keys]
|
|
28
|
+
)
|
|
29
|
+
res = get_metrics_for_model(target, "id", value_keys)
|
|
30
|
+
for i, key in enumerate(value_keys):
|
|
31
|
+
assert len(res[i]) == 13 # The current month as well as last year's are included
|
|
32
|
+
assert list(res[i].values())[-1] == len(key) * 2403 + 1
|
|
33
|
+
assert list(res[i].values())[-2] == len(key) * 2403
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_get_metrics_for_site(app, rmock):
|
|
37
|
+
value_keys = [
|
|
38
|
+
"visit_dataset",
|
|
39
|
+
"download_resource",
|
|
40
|
+
]
|
|
41
|
+
url = f"{app.config['METRICS_API']}/site/data/?metric_month__sort=desc"
|
|
42
|
+
mock_monthly_metrics_payload(
|
|
43
|
+
app, rmock, "site", data=[(value_key, 2403) for value_key in value_keys], url=url
|
|
44
|
+
)
|
|
45
|
+
res = get_metrics_for_model("site", None, value_keys)
|
|
46
|
+
for i, key in enumerate(value_keys):
|
|
47
|
+
assert len(res[i]) == 13 # The current month as well as last year's are included
|
|
48
|
+
assert list(res[i].values())[-1] == len(key) * 2403 + 1
|
|
49
|
+
assert list(res[i].values())[-2] == len(key) * 2403
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@pytest.mark.parametrize(
|
|
53
|
+
"model,factory,date_label",
|
|
54
|
+
[
|
|
55
|
+
(Dataset, DatasetFactory, "created_at_internal"),
|
|
56
|
+
(Dataservice, DataserviceFactory, "created_at"),
|
|
57
|
+
(Reuse, ReuseFactory, "created_at"),
|
|
58
|
+
(Organization, OrganizationFactory, "created_at"),
|
|
59
|
+
],
|
|
60
|
+
)
|
|
61
|
+
def test_get_stock_metrics(app, clean_db, model, factory, date_label):
|
|
62
|
+
[factory() for i in range(10)]
|
|
63
|
+
[factory(**{date_label: datetime.now().replace(day=1) - timedelta(days=1)}) for i in range(8)]
|
|
64
|
+
res = get_stock_metrics(model.objects(), date_label)
|
|
65
|
+
assert list(res.values())[-1] == 10
|
|
66
|
+
assert list(res.values())[-2] == 8
|
|
67
|
+
assert list(res.values())[-3] == 0
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from udata.core.dataservices.factories import DataserviceFactory
|
|
4
|
+
from udata.core.dataset.factories import CommunityResourceFactory, DatasetFactory, ResourceFactory
|
|
5
|
+
from udata.core.metrics.tasks import (
|
|
6
|
+
iterate_on_metrics,
|
|
7
|
+
update_dataservices,
|
|
8
|
+
update_datasets,
|
|
9
|
+
update_organizations,
|
|
10
|
+
update_resources_and_community_resources,
|
|
11
|
+
update_reuses,
|
|
12
|
+
)
|
|
13
|
+
from udata.core.organization.factories import OrganizationFactory
|
|
14
|
+
from udata.core.reuse.factories import ReuseFactory
|
|
15
|
+
|
|
16
|
+
from .helpers import mock_metrics_api
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_iterate_on_metrics(app, rmock):
|
|
20
|
+
mock_metrics_api(
|
|
21
|
+
app,
|
|
22
|
+
rmock,
|
|
23
|
+
"test_model",
|
|
24
|
+
["test_key", "second_key"],
|
|
25
|
+
[
|
|
26
|
+
{"id": 123},
|
|
27
|
+
{"id": 42},
|
|
28
|
+
{"id": 1337},
|
|
29
|
+
],
|
|
30
|
+
page_size=2,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
metrics_data = list(iterate_on_metrics("test_model", ["test_key", "second_key"], page_size=2))
|
|
34
|
+
|
|
35
|
+
assert metrics_data == [
|
|
36
|
+
{"__id": 0, "id": 123},
|
|
37
|
+
{"__id": 1, "id": 42},
|
|
38
|
+
{"__id": 2, "id": 1337},
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.mark.parametrize(
|
|
43
|
+
"endpoint,id_key,factory,func,api_key",
|
|
44
|
+
[
|
|
45
|
+
("dataservices", "dataservice_id", DataserviceFactory, update_dataservices, "visit"),
|
|
46
|
+
("reuses", "reuse_id", ReuseFactory, update_reuses, "visit"),
|
|
47
|
+
(
|
|
48
|
+
"organizations",
|
|
49
|
+
"organization_id",
|
|
50
|
+
OrganizationFactory,
|
|
51
|
+
update_organizations,
|
|
52
|
+
"visit_dataset",
|
|
53
|
+
),
|
|
54
|
+
],
|
|
55
|
+
)
|
|
56
|
+
def test_update_simple_visit_to_views_metrics(app, rmock, endpoint, id_key, factory, func, api_key):
|
|
57
|
+
models = [factory() for i in range(15)]
|
|
58
|
+
mock_metrics_api(
|
|
59
|
+
app,
|
|
60
|
+
rmock,
|
|
61
|
+
endpoint,
|
|
62
|
+
[api_key],
|
|
63
|
+
[
|
|
64
|
+
{id_key: str(models[1].id), api_key: 42},
|
|
65
|
+
{id_key: str(models[3].id), api_key: 1337},
|
|
66
|
+
{id_key: str(models[4].id), api_key: 2},
|
|
67
|
+
],
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
func()
|
|
71
|
+
[model.reload() for model in models]
|
|
72
|
+
|
|
73
|
+
assert models[1].metrics.get("views") == 42
|
|
74
|
+
assert models[3].metrics.get("views") == 1337
|
|
75
|
+
assert models[4].metrics.get("views") == 2
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_update_datasets(app, rmock):
|
|
79
|
+
datasets = [DatasetFactory() for i in range(15)]
|
|
80
|
+
mock_metrics_api(
|
|
81
|
+
app,
|
|
82
|
+
rmock,
|
|
83
|
+
"datasets",
|
|
84
|
+
["visit", "download_resource"],
|
|
85
|
+
[
|
|
86
|
+
{"dataset_id": str(datasets[1].id), "visit": 42, "download_resource": 123},
|
|
87
|
+
{"dataset_id": str(datasets[3].id), "visit": 1337, "download_resource": 4242},
|
|
88
|
+
{"dataset_id": str(datasets[4].id), "visit": 2, "download_resource": 7},
|
|
89
|
+
],
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
update_datasets()
|
|
93
|
+
[model.reload() for model in datasets]
|
|
94
|
+
|
|
95
|
+
assert datasets[1].metrics.get("views") == 42
|
|
96
|
+
assert datasets[1].metrics.get("resources_downloads") == 123
|
|
97
|
+
assert datasets[3].metrics.get("views") == 1337
|
|
98
|
+
assert datasets[3].metrics.get("resources_downloads") == 4242
|
|
99
|
+
assert datasets[4].metrics.get("views") == 2
|
|
100
|
+
assert datasets[4].metrics.get("resources_downloads") == 7
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_update_resources_metrics(app, rmock):
|
|
104
|
+
resources = [ResourceFactory() for i in range(5)]
|
|
105
|
+
dataset_a_with_resources = DatasetFactory(resources=resources)
|
|
106
|
+
dataset_b_with_resource = DatasetFactory(resources=[ResourceFactory()])
|
|
107
|
+
|
|
108
|
+
community_resources = [CommunityResourceFactory() for i in range(10)]
|
|
109
|
+
|
|
110
|
+
dataset_without_resource = DatasetFactory()
|
|
111
|
+
|
|
112
|
+
mock_metrics_api(
|
|
113
|
+
app,
|
|
114
|
+
rmock,
|
|
115
|
+
"resources",
|
|
116
|
+
["download_resource"],
|
|
117
|
+
[
|
|
118
|
+
{
|
|
119
|
+
"resource_id": str(dataset_a_with_resources.resources[0].id),
|
|
120
|
+
"dataset_id": str(dataset_a_with_resources.id),
|
|
121
|
+
"download_resource": 42,
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"resource_id": str(community_resources[3].id),
|
|
125
|
+
"dataset_id": None,
|
|
126
|
+
"download_resource": 16,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"resource_id": str(community_resources[5].id),
|
|
130
|
+
"dataset_id": None,
|
|
131
|
+
"download_resource": 111,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"resource_id": str(dataset_a_with_resources.resources[1].id),
|
|
135
|
+
"dataset_id": str(dataset_a_with_resources.id),
|
|
136
|
+
"download_resource": 1337,
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"resource_id": str(dataset_b_with_resource.resources[0].id),
|
|
140
|
+
"dataset_id": str(dataset_b_with_resource.id),
|
|
141
|
+
"download_resource": 1404,
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"resource_id": str(dataset_a_with_resources.resources[4].id),
|
|
145
|
+
"dataset_id": str(dataset_a_with_resources.id),
|
|
146
|
+
"download_resource": 2,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"resource_id": str(community_resources[9].id),
|
|
150
|
+
"dataset_id": None,
|
|
151
|
+
"download_resource": 1,
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
update_resources_and_community_resources()
|
|
157
|
+
|
|
158
|
+
dataset_a_with_resources.reload()
|
|
159
|
+
dataset_b_with_resource.reload()
|
|
160
|
+
dataset_without_resource.reload()
|
|
161
|
+
[community_resource.reload() for community_resource in community_resources]
|
|
162
|
+
|
|
163
|
+
assert community_resources[3].metrics.get("views") == 16
|
|
164
|
+
assert community_resources[5].metrics.get("views") == 111
|
|
165
|
+
assert community_resources[9].metrics.get("views") == 1
|
|
166
|
+
|
|
167
|
+
assert dataset_a_with_resources.resources[0].metrics.get("views") == 42
|
|
168
|
+
assert dataset_a_with_resources.resources[1].metrics.get("views") == 1337
|
|
169
|
+
assert dataset_a_with_resources.resources[4].metrics.get("views") == 2
|
|
170
|
+
|
|
171
|
+
assert dataset_b_with_resource.resources[0].metrics.get("views") == 1404
|
|
Binary file
|