Commit f5682b9d authored by Romain Loth's avatar Romain Loth

finally harmonize all date processing with DB type date and timestamp, python...

finally harmonize all date processing with DB type date and timestamp, python conversion to and from + fix job_looking_date pre-selection + add job_looking boolean to DB
parent 3f2554e9
......@@ -19,7 +19,7 @@ CREATE TABLE scholars (
luid int(15) not null auto_increment unique primary key,
-- doors uid common to all lab's services
doors_uid char(36) unique,
last_modified_date char(24) not null,
last_modified timestamp,
email varchar(255) not null unique,
country varchar(60) not null,
first_name varchar(30) not null,
......@@ -31,7 +31,8 @@ CREATE TABLE scholars (
hon_title varchar(30), -- eg Doctor
interests_text varchar(3500),
gender char(1),
job_looking_date char(24), -- null if not looking for a job
job_looking boolean,
job_looking_date date,
home_url varchar(180), -- homepage
pic_url varchar(180), -- remote pic... (full url)
pic_fname varchar(120), -- ...or locally saved pic (basename)
......
......@@ -21,7 +21,7 @@ USER_COLS = [
# NAME, NOT NULL, N or MAXCHARS (if applicable)
("luid", True, 15),
("doors_uid", False, 36),
("last_modified_date", True, 24),
# ("last_modified", True, None), # autoset on update
("email", True, 255),
("country", True, 60),
("first_name", True, 30),
......@@ -33,6 +33,7 @@ USER_COLS = [
("hon_title", False, 30),
("interests_text", False, 1200),
("gender", False, 1),
("job_looking", False, 1),
("job_looking_date", False, 24),
("home_url", False, 120),
("pic_url", False, 120),
......@@ -430,18 +431,17 @@ def get_full_scholar(uid, cmx_db = None):
# 'email': 'jfk@usa.com', 'first_name': 'John', 'gender': 'M',
# 'home_url': 'http://localhost/regcomex/', 'hon_title': 'Student',
# 'initials': 'JFK', 'interests_text': 'Blablabla',
# 'job_looking_date': '2019_09_28T22:00:00.000Z',
# 'job_looking_date': datetime.date(2019, 9, 28),
# 'hashtags': '#eccs15', 'hashtags_nb': 1,
# 'keywords': 'complex networks,complex systems,text mining,machine learning', 'keywords_nb': 4,
# 'last_modified_date': '2016-12-07T15:56:09.721Z',
# 'last_modified_date': datetime.datetime(2017, 2, 22, 12, 25, 59),
# 'last_name': 'Kennedy',
# 'linked_ids': 'twitter:@jfk,yoyo:42,foobar:XWING', 'linked_ids_nb': 3,
# 'middle_name': 'Fitzgerald',
# 'org': 'Centre National de la Recherche Scientifique (CNRS)',
# 'org_city': 'Paris', 'org_type': 'public R&D org',
# 'pic_fname': '12345.jpg', 'pic_url': None, 'position': 'Research Fellow',
# 'record_status': None, 'team_lab': 'ISCPIF'}
# 'record_status': 'legacy', 'valid_date': datetime.date(2017, 5, 22)}
# post-treatments
# ---------------
......
......@@ -25,7 +25,7 @@ __status__ = "Dev"
# ============== imports ==============
from re import sub
from re import sub, match
from os import path
from json import dumps
from datetime import timedelta
......@@ -82,10 +82,9 @@ login_manager.init_app(app)
# all inputs as they are declared in form, as a couple
SOURCE_FIELDS = [
# NAME, SANITIZE? Specificity
# NAME, SANITIZE? sanitizing specificity
("luid", False, None),
("doors_uid", False, None),
("last_modified_date", False, None), # TODO use stamp
("email", True, None),
("country", True, None),
("first_name", True, None),
......@@ -98,7 +97,8 @@ SOURCE_FIELDS = [
("hon_title", True, None),
("interests_text", True, None),
("gender", False, None), # M|F
("job_looking_date", True, "sdate"), # def null: not looking for a job
("job_looking", True, "sbool"),
("job_looking_date", True, "sdate"),
("home_url", True, "surl"), # scholar's homepage
("pic_url", True, "surl"),
("pic_file", False, None), # saved separately
......@@ -863,6 +863,14 @@ def sanitize(value, specific_type=None):
if not specific_type:
san_val = sub(r'[^\w@\.:,()# -]', '_', clean_val)
elif specific_type == "sbool":
# DB uses int(0) or int(1)
if match('^[01]$',clean_val):
san_val = int(clean_val)
else:
san_val = 0
# NB san_val_bool = bool(san_val)
elif specific_type == "surl":
san_val = sub(r'[^\w@\.: -/]', '_', clean_val)
elif specific_type == "sdate":
......
......@@ -9,7 +9,7 @@ __copyright__ = "Copyright 2016 ISCPIF-CNRS"
__email__ = "romain.loth@iscpif.fr"
from json import dumps, loads
from datetime import date
from datetime import date, datetime
from flask_login import LoginManager
from re import match
......@@ -52,16 +52,28 @@ def jsonize_uinfo(uinfo_dict):
Dumps user_info in json format for client-side needs
"""
# most fields are already serializable
serializable_dict = {k:v for k,v in uinfo_dict.items() if k not in ['valid_date']}
serializable_dict = {}
for k,v in uinfo_dict.items():
mlog('DEBUG', 'user: jsonize_uinfo k=v', k, '=' , v)
if 'valid_date' in uinfo_dict and uinfo_dict['valid_date'] is not None:
d = uinfo_dict['valid_date']
if type(d) != date:
raise TypeError("Incorrect type for valid_date: '%s' instead of 'date'" % type(d))
# most values are already serializable
if ( v is None
or k not in [ 'last_modified',
'valid_date',
'job_looking_date' ]
):
serializable_dict[k] = v
# when k is a non-empty date field
else:
# "YYYY-MM-DD"
serializable_dict['valid_date'] = d.isoformat()
# if type(v) != date or type(v) != datetime:
if type(v) not in [date, datetime]:
raise TypeError("Incorrect type for %s field: /%s/ instead of date or datetime" % (k, type(v)))
else:
print("toto")
serializable_dict[k] = v.isoformat()
# date "YYYY-MM-DD"
# datetime "YYYY-MM-DDTHH:MM:SS"
return dumps(serializable_dict)
......
......@@ -12,7 +12,7 @@ CREATE TABLE scholars (
luid int(15) not null auto_increment unique primary key,
-- doors uid common to all lab's services
doors_uid char(36) unique,
last_modified_date char(24) not null,
last_modified timestamp,
email varchar(255) not null unique,
country varchar(60) not null,
first_name varchar(30) not null,
......@@ -24,7 +24,8 @@ CREATE TABLE scholars (
hon_title varchar(30), -- eg Doctor
interests_text varchar(3500),
gender char(1),
job_looking_date char(24), -- null if not looking for a job
job_looking boolean,
job_looking_date date,
home_url varchar(180), -- homepage
pic_url varchar(180), -- remote pic... (full url)
pic_fname varchar(120), -- ...or locally saved pic (basename)
......
......@@ -121,11 +121,7 @@ function completionAsYouGo() {
cmxClt.uform.simpleValidateAndMessage(theUForm, diagnosticParams)
// stamp => #last_modified_date
cmxClt.uform.stampTime(theUForm)
// debug
// console.log("timestamp:", cmxClt.uform.timestamp.value)
// timestamp is done server-side
}
// run first check on existing profile data pre-filled by the template
......
/**
* @fileoverview
* Validates the comex (communityexplorer.org) registration form
* + adds a timestamp in input#last_modified_date
* + adds autocompletes
* + prepares DB save into cmxClt.COLS
*
......@@ -67,8 +66,6 @@ function testAsYouGo() {
else {
regfo.elSubmitBtn.disabled = true
}
// stamp => #last_modified_date
cmxClt.uform.stampTime(regfo)
}
var teamCityDivStyle = document.getElementById('team_city_div').style
......
......@@ -43,9 +43,8 @@ var cmxClt = (function() {
// ==> *hashtags* table
["doors_uid", true, "auto" , "t", null],
["last_modified_date", true, "auto" , "d", null],
["hon_title", false, "plsfill", "t", "basic_infos"],
["email", true, "plsfill", "t", "login_infos"],
["hon_title", false, "plsfill", "t", "basic_infos"],
["first_name", true, "plsfill", "t", "basic_infos"],
["middle_name", false, "pref", "t", "basic_infos"],
["last_name", true, "plsfill", "t", "basic_infos"],
......@@ -54,6 +53,7 @@ var cmxClt = (function() {
["position", true, "plsfill", "t", "map_infos"],
["interests_text", false, "pref", "t", "other_infos"],
["gender", false, "plsfill", "m", "other_infos"],
["job_looking", false, "pref" , "m", "map_infos"],
["job_looking_date", false, "pref" , "d", "map_infos"],
["home_url", false, "plsfill", "t", "other_infos"],
["pic_url", false, "pref" , "t", "other_infos"],
......@@ -338,7 +338,7 @@ var cmxClt = (function() {
var mainMessageId, timestampId, buttonId
mainMessageId = fParams.mainMessageId || 'main_message'
timestampId = fParams.timestampId || 'last_modified_date'
timestampId = fParams.timestampId || 'form_timestamp'
submitBtnId = fParams.submitBtnId || 'form_submit'
myUform.elMainMessage = document.getElementById(mainMessageId)
......@@ -511,8 +511,7 @@ var cmxClt = (function() {
otherMissingFields ]
}
// simple timestamp on #last_modified_date element
// ------------------
// simple timestamp if needed
cC.uform.stampTime = function (aUForm) {
var now = new Date()
aUForm.elTimestamp.value = now.toISOString()
......
......@@ -297,7 +297,7 @@
{% endif %}
{% if return_user.info.job_looking_date or return_user.info.hashtags %}
{% if return_user.info.job_looking or return_user.info.hashtags %}
<h3 class="formcat"> About your future activities </h3>
......@@ -306,11 +306,11 @@
{% if return_user.info.job_looking %}
<div class="question">
<div class="input-group">
<label for="job_bool" class="smlabel input-group-addon">Job offers</label>
<select disabled id="job_bool" name="job_bool"
<label for="job_looking" class="smlabel input-group-addon">Job offers</label>
<select disabled id="job_looking" name="job_looking"
class="custom-select form-control">
<option selected value="No">No</option>
<option value="Yes">Yes</option>
<option selected value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
</div>
......
......@@ -311,11 +311,11 @@
<div class="question">
<div class="input-group">
<label for="job_bool" class="smlabel input-group-addon">Soon on the job market? <br/><small>and do you want our job contacts?</small></label>
<select id="job_bool" name="job_bool"
<label for="job_looking" class="smlabel input-group-addon">Soon on the job market? <br/><small>and do you want our job contacts?</small></label>
<select id="job_looking" name="job_looking"
class="custom-select form-control">
<option selected value="No">No</option>
<option value="Yes">Yes</option>
<option selected value="0">No</option>
<option value="1">Yes</option>
</select>
</div>
<!-- job_looking_date_div <=> only if previous choice == Yes -->
......@@ -534,11 +534,6 @@
</div>
<!-- hidden input for modification date -->
<input id="last_modified_date" name="last_modified_date" type="text" hidden>
</input>
<!-- hidden input for main user id -->
<input id="luid" name="luid" type="text" hidden
value="{{ current_user.uid | safe }}">
......
......@@ -182,10 +182,6 @@
<input id="doors_connect" name="doors_connect" type="text" hidden value="{{doors_connect|safe}}">
</input>
<!-- hidden input for modification date -->
<input id="last_modified_date" name="last_modified_date" type="text" hidden>
</input>
<!-- hidden input for doors user id -->
<input id="doors_uid" name="doors_uid" type="text" hidden>
</input>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment