diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 331e7cc..9dc659e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,22 +1,27 @@ +--- name: Validate CSV - on: + push: + branches: + - main pull_request: - + branches: + - main +permissions: + contents: write jobs: test-build: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Python - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: "3.11" - - - name: Install dependencies - run: pip install -r linters/requirements.txt - - - name: Validate CSV - run: python linters/lint-csv.py + python-version: "3.12" + - run: pip install -r linters/requirements.txt + - run: python linters/lint-csv.py + - run: python linters/autoformat-csv.py + - run: | + git config --global user.name 'Jon Banafato' + git config --global user.email 'jonafato@users.noreply.github.com' + git commit -am "Autoformat CSV" + git push diff --git a/2019.csv b/2019.csv index 29c87ab..8bec4c9 100644 --- a/2019.csv +++ b/2019.csv @@ -42,7 +42,7 @@ PyGotham,2019-10-04,2019-10-05,"New York, New York, United States of America",US PyCon España,2019-10-04,2019-10-06,"Alicante, Alicante, Spain",ESP,,,2019-05-10,https://2019.es.pycon.org,https://easychair.org/cfp/pycones2019, PyCon Germany & PyData Berlin,2019-10-09,2019-10-13,"Berlin, Brandenburg, Germany",DEU,Kosmos,2019-06-09,2019-06-09,https://de.pycon.org,https://de.pycon.org/call-for-proposals,https://de.pycon.org/sponsors PyCon mini Hiroshima,2019-10-12,2019-10-12,"Hiroshima, Chugoku, Japan",JPN,"Satellite Campus, Horoshima City Unversity",,,https://hiroshima.pycon.jp/2019,https://docs.google.com/forms/d/e/1FAIpQLSdIebD2ijyIFFKAtlR-iYiYWs8kPbP8ZMXNSaw0iiXeC57szA/viewform, -PythonDay México,2019-10-18,2019-10-19,"Mexico City, Federal District, Mexico",MEX,"Auditorio Javier Barros Sierra, Facultad de Ingeniería e IIMAS. UNAM, ",2019-09-27,2019-09-27,http://pythonday.mx,https://www.papercall.io/pythondaymx2019, +PythonDay México,2019-10-18,2019-10-19,"Mexico City, Federal District, Mexico",MEX,"Auditorio Javier Barros Sierra, Facultad de Ingeniería e IIMAS, UNAM",2019-09-27,2019-09-27,http://pythonday.mx,https://www.papercall.io/pythondaymx2019, Python Brasil,2019-10-23,2019-10-28,"Ribeirão Preto, São Paulo, Brazil",BRA,Centro de Convenções Ribeirão Preto (CCRP),,,https://pythonbrasil.org.br,https://2019.pythonbrasil.org.br/submissao-de-palestras,https://2019.pythonbrasil.org.br/assets/pdfs/sponsorship_plan.pdf PyCon Sweden,2019-10-31,2019-11-01,"Stockholm, Stockholm County, Sweden",SWE,Münchenbryggeriet,2019-09-13,2019-09-13,http://www.pycon.se,https://forms.gle/hZWhUePsHB34xtUM9,http://www.pycon.se/sponsorship.html PyCon France,2019-10-31,2019-11-03,"Bordeaux, Nouvelle-Aquitaine, France",FRA,Université Bordeaux,,,https://www.pycon.fr/2019,, diff --git a/2023.csv b/2023.csv index bf6630c..1ded986 100644 --- a/2023.csv +++ b/2023.csv @@ -7,7 +7,7 @@ GeoPython,2023-03-06,2023-03-08,"Basel, Basel-Stadt, Switzerland",CHE,FHNW,,2022 Python Web Conf,2023-03-13,2023-03-17,"Fishers, Indiana, United States of America",USA,Online,,2022-10-01,https://2023.pythonwebconf.com,, PyCascades,2023-03-18,2023-03-19,"Vancouver, British Columbia, Canada",CAN,SFU Harbour Centre (Vancouver Campus),,2022-11-16,https://2023.pycascades.com,,https://2023.pycascades.com/sponsors/become-a-sponsor PyTexas,2023-04-01,2023-04-02,"Austin, Texas, United States of America",USA,Austin Central Public Library,,2023-01-15,https://www.pytexas.org,https://pretalx.com/pytexas-2023,https://www.pytexas.org/sponsors/prospectus -PyCon DE & PyData Berlin,2023-04-17,2023-04-19,"Berlin, Brandenburg, Germany",DEU,bcc Berlin Congress Center,2023-01-05,2023-01-05,https://2023.pycon.de,https://2023.pycon.de/blog/call-for-proposals,https://2023.pycon.de/blog/pyconde-pydata-berlin-call-for-sponsors +PyCon DE & PyData Berlin,2023-04-17,2023-04-19,"Berlin, Brandenburg, Germany",DEU,Berlin Congress Center,2023-01-05,2023-01-05,https://2023.pycon.de,https://2023.pycon.de/blog/call-for-proposals,https://2023.pycon.de/blog/pyconde-pydata-berlin-call-for-sponsors PyCon US,2023-04-19,2023-04-27,"Salt Lake City, Utah, United States of America",USA,Salt Palace Convention Center,2022-12-11,2022-12-11,https://us.pycon.org/2023,https://us.pycon.org/2023/speaking/guidelines,https://us.pycon.org/2023/sponsorship/why-sponsor PyData Seattle,2023-04-26,2023-04-28,"Seattle, USA",USA,,,2023-02-06,https://pydata.org/seattle2023/,,https://pydata.org/seattle2023/wp-content/uploads/2022/12/PyData-2023-Sponsorship-Prospectus.pdf JupyterCon,2023-05-10,2023-05-12,"Paris, Île-de-France, France",FRA,Cité des Sciences,,2022-12-20,https://jupytercon.com,,https://www.jupytercon.com/sponsors @@ -24,8 +24,8 @@ SciPy,2023-07-10,2023-07-16,"Austin, Texas, United States of America",USA,AT&T C EuroPython,2023-07-17,2023-07-23,"Prague, Bohemia, Czech Republic",CZE,The Prague Congress Centre,,2023-03-26,https://europython.eu,https://ep2023.europython.eu/cfp,https://ep2023.europython.eu/sponsor/information AfroPython Conf,2023-07-22,2023-07-22,"Salvador, Bahia, Brazil",BRA,,,2023-06-19,https://afropython.org/conf2023,https://bit.ly/conf2023-palestrantes,https://afropythonconf.org/#patrocinadores PyCon Russia,2023-07-28,2023-07-29,"Moscow, Central Federal District, Russia",RUS,Digital Business Space,,2023-03-15,https://pycon.ru,https://pycon.ru/cfp,https://pycon.ru/partneram -PyCamp Leipzig,2023-07-29,2023-07-30,"Leipzig, Saxony, Germany",DEU,Basislager Coworking,,,https://barcamps.eu/python-barcamp-der-leipzig-python-user-group-2023,, North Bay Python,2023-07-29,2023-07-30,"Petaluma, California, United States of America",USA,Reis River Ranch,,2023-05-19,https://2023.northbaypython.org,https://2023.northbaypython.org/speak,https://2023.northbaypython.org/sponsor +PyCamp Leipzig,2023-07-29,2023-07-30,"Leipzig, Saxony, Germany",DEU,Basislager Coworking,,,https://barcamps.eu/python-barcamp-der-leipzig-python-user-group-2023,, PyCon Korea,2023-08-11,2023-08-13,"Seoul, Seoul Capital Area, South Korea",KOR,COEX Grand Ballroom & ASEM Ballroom,,2023-05-14,https://2023.pycon.kr,https://2023.pycon.kr/cfp/apply,https://2023.pycon.kr/sponsor/join EuroSciPy,2023-08-14,2023-08-18,"Basel, Basel-Stadt, Switzerland",CHE,"Kollegienhaus, University of Basel",,2023-05-14,https://www.euroscipy.org/2023,https://www.euroscipy.org/2023/program.html,https://www.euroscipy.org/2023/sponsoring.html DjangoCon Australia,2023-08-18,2023-08-18,"Tarndanya (Adelaide), Australia",AUS,Adelaide Convention Centre,,2023-05-14,https://2023.djangocon.com.au,https://2023.pycon.org.au/program,https://2023.pycon.org.au/sponsor @@ -36,19 +36,19 @@ PyCon Taiwan,2023-09-02,2023-09-03,"Taipei, Northern Taiwan, Taiwan",TWN,,,2023- PyCon Estonia,2023-09-07,2023-09-08,"Tallinn, Harju, Estonia",EST,"Astra building, Tallinn University",2023-05-09,2023-05-09,https://pycon.ee,https://pyconestonia.typeform.com/to/hBOEtTQ3, PyCon Portugal,2023-09-07,2023-09-09,"Coimbra, Coimbra, Portugal",PRT,Coimbra Business School,2023-06-30,2023-06-30,https://2023.pycon.pt,https://2023.pycon.pt/talks/cfp,https://2023.pycon.pt/sponsors/sponsorship PyData Amsterdam,2023-09-14,2023-09-16,"Amsterdam, North Holland, The Netherlands",NLD,Kromhout Hal,2023-06-11,2023-06-11,https://amsterdam.pydata.org,https://amsterdam2023.pydata.org/cfp/cfp,https://amsterdam.pydata.org/sponsor -PyCon CZ,2023-09-15,2023-09-17,"Prague, Czech republic",CZE,Gabriel Loci,2023-06-25,2023-06-25,https://cz.pycon.org/2023,https://cz.pycon.org/2023/cfp,https://cz.pycon.org/2023/sponsorship Kiwi PyCon,2023-09-15,2023-09-17,"Waihōpai (Invercargill), Aotearoa, New Zealand",NZL,Ascot Park Hotel,,2023-05-19,https://kiwipycon.nz,https://kiwipycon.nz/call-for-proposals,https://kiwipycon.nz/sponsorship -PyCon Uganda,2023-09-21,2023-09-23,"MoTIV, Kampala, Uganda",UGA,,,2023-05-05,https://ug.pycon.org,https://ug.pycon.org/speakers,https://ug.pycon.org/sponsors +PyCon CZ,2023-09-15,2023-09-17,"Prague, Czech Republic",CZE,Gabriel Loci,2023-06-25,2023-06-25,https://cz.pycon.org/2023,https://cz.pycon.org/2023/cfp,https://cz.pycon.org/2023/sponsorship Swiss Python Summit,2023-09-21,2023-09-21,"Rapperswil, Rapperswil-Jona, Switzerland",CHE,OST Eastern Switzerland University of Applied Sciences,,2023-07-01,https://www.python-summit.ch,https://www.python-summit.ch/cfp,https://www.python-summit.ch/helpus +PyCon Uganda,2023-09-21,2023-09-23,"MoTIV, Kampala, Uganda",UGA,,,2023-05-05,https://ug.pycon.org,https://ug.pycon.org/speakers,https://ug.pycon.org/sponsors PyCon UK,2023-09-22,2023-09-25,"Cardiff, Wales, United Kingdom",GBR,Cardiff City Hall,,2023-06-30,https://2023.pyconuk.org,https://2023.pyconuk.org/call-for-proposals/,https://2023.pyconuk.org/sponsorship PyCon India,2023-09-29,2023-10-02,"Hyderabad, Telangana, India",IND,,,2023-08-05,https://in.pycon.org/2023,https://in.pycon.org/cfp/pycon-india-2023/proposals/,https://docs.google.com/forms/d/13MVcj2XEF1DfTmV3fPjq9SN5qzY22k3R7cJVKlfbhZ4/ -DjangoDay Copenhagen,2023-10-06,2023-10-06,"Copenhagen, Denmark",,,,2023-08-31,https://2023.djangoday.dk/,https://2023.djangoday.dk/cfp/, PyCon South Africa,2023-10-05,2023-10-06,"Umhlanga, Durban, South Africa",ZAF,Premier Splendid Inn,2023-08-18,2023-08-18,https://za.pycon.org,https://za.pycon.org/talks/how-to-submit-a-talk, +DjangoDay Copenhagen,2023-10-06,2023-10-06,"Copenhagen, Denmark",,,,2023-08-31,https://2023.djangoday.dk/,https://2023.djangoday.dk/cfp/, PyGotham TV,2023-10-06,2023-10-07,"New York, New York, United States of America",USA,Online,,2023-05-15,https://2023.pygotham.tv,https://cfp.pygotham.tv,https://2023.pygotham.tv/sponsors/prospectus PyCon España,2023-10-06,2023-10-08,"Tenerife, Canary Islands, Spain",ESP,Universidad de La Laguna,,2023-06-23,https://2023.es.pycon.org,https://2023.es.pycon.org/c4p,https://2023.es.pycon.org/patrocinios PyHEP,2023-10-09,2023-10-12,Online,,,,2023-09-06,https://indico.cern.ch/e/PyHEP2023,https://indico.cern.ch/event/1252095/abstracts/, -PyCon MEA @GlobalDevSlam,2023-10-16,2023-10-20,"Dubai, UAE",ARE,,,2023-05-31,https://globaldevslam.com/,, DjangoCon US,2023-10-16,2023-10-20,"Durham, North Carolina, United States of America",USA,Durham Convention Center,2023-05-15,2023-05-15,https://2023.djangocon.us,https://2023.djangocon.us/speaking,https://2023.djangocon.us/sponsors/information +PyCon MEA @GlobalDevSlam,2023-10-16,2023-10-20,"Dubai, UAE",ARE,,,2023-05-31,https://globaldevslam.com/,, EduPy,2023-10-21,2023-10-21,"Cali, Colombia",,,,2023-10-14,https://slec.net/edupy/,https://bit.ly/ConferencistaEdupyOctubre2023,https://slec.net/edupy/posts/callforsponsors/ PackagingCon,2023-10-26,2023-10-28,"Berlin, Germany",DEU,,,2023-08-06,https://packaging-con.org/,https://cfp.packaging-con.org/2023/cfp,https://packaging-con.org/s/sponsorship_prospectus_packagingcon_2023.pdf PyCon Asia Pacific,2023-10-27,2023-10-29,"Tokyo, Kantō, Japan",JPN,TOC Ariake Convention Hall,,2023-05-31,https://2023-apac.pycon.jp,https://pretalx.com/pyconapac2023/cfp,https://pyconjp.blogspot.com/2023/05/pyconapac2023-call-for-sponsors-en.html @@ -68,4 +68,4 @@ Pyjamas Conf,2023-12-09,2023-12-11,Online,,,,,https://pyjamas.live,, PyCon Thailand,2023-12-15,2023-12-16,"Bangkok, Thailand",THA,,2023-08-16,2023-08-16,https://th.pycon.org,https://www.papercall.io/pyconth2023,https://shorturl.at/kqrL4 PyOhio,2023-12-16,2023-12-16,"Ohio, United States of America",USA,Online,,,https://www.pyohio.org/2023/,, FlaskCon,2023-12-16,2023-12-17,Online,,,,2023-10-31,https://flaskcon.com/2023/,,https://flaskcon.com/2023/become-sponsor -PyCon Somalia,2023-12-26,2023-12-27,"Mogadishu, Somalia",SOM,,,,https://pycon.org.so/,, \ No newline at end of file +PyCon Somalia,2023-12-26,2023-12-27,"Mogadishu, Somalia",SOM,,,,https://pycon.org.so/,, diff --git a/2024.csv b/2024.csv index a59500b..bb1e3fa 100644 --- a/2024.csv +++ b/2024.csv @@ -41,8 +41,8 @@ PyCon Taiwan,2024-09-21,2024-09-22,TBD,TWN,TBD,2024-04-08,2024-04-08,https://tw. DjangoCon US,2024-09-22,2024-09-27,"Durham, USA",USA,,,2024-04-24,https://2024.djangocon.us/,https://2024.djangocon.us/speaking/, PyCon Africa,2024-09-24,2024-09-28,"Accra, Ghana",GHA,Cedi Conference Center,2024-07-08,2024-07-08,https://africa.pycon.org/2024/,https://africa.pycon.org/2024/talks/speaking/,https://africa.pycon.org/2024/sponsor-us/ PyData Paris,2024-09-25,2024-09-26,"Paris, France",FRA,,,2024-04-08,https://pydata.org/paris2024/,https://pydata.org/paris2024/cfp/, -PyCon JP,2024-09-26,2024-09-29,"Tokyo, Japan",JPN,TOC Ariake Convention Hall,,2024-05-31,https://2024.pycon.jp/,https://pretalx.com/pyconjp2024/cfp, Piter Py,2024-09-26,2024-09-27,"Saint Petersburg, Russia",RUS,,,2024-06-01,https://piterpy.com/en/,, +PyCon JP,2024-09-26,2024-09-29,"Tokyo, Japan",JPN,TOC Ariake Convention Hall,,2024-05-31,https://2024.pycon.jp/,https://pretalx.com/pyconjp2024/cfp, PyConZA (South Africa),2024-10-03,2024-10-04,"Cape Town, South Africa",ZAF,Belmont Square Conference Centre,2024-08-18,2024-08-18,https://za.pycon.org/,https://za.pycon.org/talks/how-to-submit-a-talk/, PyCon Spain,2024-10-04,2024-10-06,"Vigo, Spain",ESP,,,,https://2024.es.pycon.org/,, PyCon Uganda,2024-10-09,2024-10-13,"Kampala, Uganda",UGA,NWSC International Resource Center,2024-04-30,2024-04-30,https://ug.pycon.org/2024,https://www.papercall.io/pyconug,https://ug.pycon.org/2024/sponsors diff --git a/linters/autoformat-csv.py b/linters/autoformat-csv.py new file mode 100644 index 0000000..da1b6fa --- /dev/null +++ b/linters/autoformat-csv.py @@ -0,0 +1,30 @@ +from csv import DictReader, DictWriter, QUOTE_MINIMAL +from pathlib import Path + + +FOLDER = Path(__file__).resolve().parent.parent + + +def main(): + for path in FOLDER.glob('*.csv'): + with path.open(mode='rt') as f: + reader = DictReader(f, dialect='unix') + rows = list(reader) + + rows.sort(key=lambda row: ( + row['Start Date'], row['End Date'], row['Subject'])) + + for row in rows: + for key, value in row.items(): + row[key] = value.strip() + + with path.open(mode='wt') as f: + writer = DictWriter( + f, fieldnames=rows[0].keys(), dialect='unix', + quoting=QUOTE_MINIMAL) + writer.writeheader() + writer.writerows(rows) + + +if __name__ == '__main__': + main() diff --git a/linters/lint-csv.py b/linters/lint-csv.py index e0b26e5..2d52634 100644 --- a/linters/lint-csv.py +++ b/linters/lint-csv.py @@ -11,14 +11,16 @@ Ignore, SetValidator, Validator, - ValidationException, -) + ValidationException) + + +FOLDER = Path(__file__).resolve().parent.parent -CSV_PATH = Path(__file__).resolve().parent.parent # NOTE: This validator doesn't actually use the field argument, but it # needs to be registered on a field in order to be used. class RowLengthValidator(Validator): + def __init__(self, **kwargs): super().__init__(**kwargs) self.invalid_rows = [] @@ -39,18 +41,17 @@ def validate(self, field, row): expected_length = len(row) - 1 length = len(row) + len(row[None]) - 1 raise ValidationException( - f"Expected {expected_length} fields, got {length}" - ) + f'Expected {expected_length} fields, got {length}') # Similarly, there is a `csv.DictReader.restval` attribute that # handles the case where there are fewer than expected rows. if None in row.values(): self.invalid_rows.append(row) expected_length = len(row) - length = len([value for value in row.values() if value is not None]) + length = len([ + value for value in row.values() if value is not None]) raise ValidationException( - f"Expected {expected_length} fields, got {length}" - ) + f'Expected {expected_length} fields, got {length}') @property def bad(self): @@ -58,45 +59,43 @@ def bad(self): class ISOFormatDateValidator(CastValidator): + def __init__(self, **kwargs): super().__init__(**kwargs) self.cast = date.fromisoformat class ConferencesValidator(Vlad): + def __init__(self, *args, **kwargs): # See https://github.com/di/vladiate/issues/35 for the reason # this needs to be defined in __init__ instead of at the class # level. self.validators = { - "Subject": [NotEmptyValidator(), RowLengthValidator()], - "Start Date": [ISOFormatDateValidator()], - "End Date": [ISOFormatDateValidator()], - "Location": [Ignore()], - "Country": [ + 'Subject': [NotEmptyValidator(), RowLengthValidator()], + 'Start Date': [ISOFormatDateValidator()], + 'End Date': [ISOFormatDateValidator()], + 'Location': [Ignore()], + 'Country': [ SetValidator( valid_set={country.alpha3 for country in countries}, - empty_ok=True, - ), - ], - "Venue": [Ignore()], - "Tutorial Deadline": [ISOFormatDateValidator(empty_ok=True)], - "Talk Deadline": [ISOFormatDateValidator(empty_ok=True)], - "Website URL": [Ignore()], - "Proposal URL": [Ignore()], - "Sponsorship URL": [Ignore()], - } + empty_ok=True)], + 'Venue': [Ignore()], + 'Tutorial Deadline': [ISOFormatDateValidator(empty_ok=True)], + 'Talk Deadline': [ISOFormatDateValidator(empty_ok=True)], + 'Website URL': [Ignore()], + 'Proposal URL': [Ignore()], + 'Sponsorship URL': [Ignore()]} super().__init__(*args, **kwargs) def main(): any_error = False - for path in sorted(CSV_PATH.glob("*.csv")): + for path in sorted(FOLDER.glob('*.csv')): error = not ConferencesValidator(source=LocalFile(path)).validate() any_error = any_error or error - sys.exit(any_error) -if __name__ == "__main__": +if __name__ == '__main__': main()