-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
merged repo & history from https://github.com/martin-bertele/ftcon24eu
- Loading branch information
1 parent
a1826aa
commit 6250e11
Showing
116 changed files
with
7,789 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import 'models/models.dart'; | ||
import 'parse_jsons.dart'; | ||
import 'write_readme.dart'; | ||
import 'write_speakers.dart'; | ||
import 'write_socials.dart'; | ||
import 'write_levels.dart'; | ||
import 'write_formats.dart'; | ||
import 'write_companies.dart'; | ||
import 'write_rooms.dart'; | ||
import 'write_descriptions.dart'; | ||
import 'write_agenda.dart'; | ||
|
||
Future<void> main() async { | ||
final List<Talk> talks = []; | ||
final List<Speaker> speakers = []; | ||
final List<Company> companies = []; | ||
|
||
// speakers and companies are unique. | ||
await parseJsons(talks, speakers, companies); | ||
|
||
// sort alphabetically | ||
talks.sort((a, b) => a.title.compareTo(b.title)); | ||
speakers.sort((a, b) => a.name.compareTo(b.name)); | ||
companies.sort((a, b) => a.name.compareTo(b.name)); | ||
|
||
writeReadme(talks); | ||
writeSpeakers(speakers, talks); | ||
writeSocials(speakers); | ||
writeLevels(talks); | ||
writeFormats(talks); | ||
writeRooms(talks); | ||
writeDescriptions(talks); | ||
writeAgenda(talks); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import 'models.dart'; | ||
|
||
class Company { | ||
final String name; | ||
final String? url; | ||
final List<Speaker> speakers; | ||
|
||
Company({ | ||
required this.name, | ||
this.url, | ||
required this.speakers, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Utility class to hold the function | ||
class UrlHelper { | ||
static String toUrl(String handleOrUrl, String platform) { | ||
String baseUrl; | ||
switch (platform.toLowerCase()) { | ||
case 'github': | ||
baseUrl = 'https://github.com/'; | ||
break; | ||
case 'linkedin': | ||
baseUrl = 'https://www.linkedin.com/in/'; | ||
break; | ||
case 'x': | ||
baseUrl = 'https://x.com/'; | ||
break; | ||
default: | ||
throw ArgumentError('Unsupported platform: $platform'); | ||
} | ||
|
||
// Check if the handleOrUrl already contains the base URL | ||
if (handleOrUrl.contains(baseUrl)) { | ||
return handleOrUrl; | ||
} else { | ||
return '$baseUrl$handleOrUrl'; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
class Hyperlink { | ||
final String label; | ||
final String url; | ||
|
||
Hyperlink({ | ||
required this.label, | ||
required this.url, | ||
}); | ||
|
||
factory Hyperlink.fromJson(Map<String, dynamic> json) => Hyperlink( | ||
label: json['label'], | ||
url: json['url'], | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export 'company.dart'; | ||
export 'helpers.dart'; | ||
export 'hyperlink.dart'; | ||
export 'recommendation.dart'; | ||
export 'speaker.dart'; | ||
export 'talk.dart'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
class Recommendation { | ||
final String tool; | ||
final String? comment; | ||
final String? url; | ||
|
||
Recommendation({ | ||
required this.tool, | ||
this.comment, | ||
this.url, | ||
}); | ||
|
||
factory Recommendation.fromJson(Map<String, dynamic> json) => Recommendation( | ||
tool: json['tool'], | ||
comment: json['comment'], | ||
url: json['url'], | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import 'helpers.dart'; | ||
|
||
class Speaker { | ||
final String name; | ||
final String? bio; | ||
final String? companyName; | ||
final String? companyUrl; | ||
final String? githubUrlOrHandle; | ||
final String? xUrlOrHandle; | ||
final String? linkedinUrlOrHandle; | ||
final String? webUrl; | ||
|
||
Speaker({ | ||
required this.name, | ||
this.bio, | ||
this.companyName, | ||
this.companyUrl, | ||
this.githubUrlOrHandle, | ||
this.xUrlOrHandle, | ||
this.linkedinUrlOrHandle, | ||
this.webUrl, | ||
}); | ||
|
||
factory Speaker.fromJson(Map<String, dynamic> json) => Speaker( | ||
name: json['name'], | ||
bio: json['bio'], | ||
companyName: json['companyName'], | ||
companyUrl: json['companyUrl'], | ||
githubUrlOrHandle: json['githubUrlOrHandle'], | ||
xUrlOrHandle: json['xUrlOrHandle'], | ||
linkedinUrlOrHandle: json['linkedinUrlOrHandle'], | ||
webUrl: json['webUrl'], | ||
); | ||
|
||
String? get githubLink => githubUrlOrHandle != null | ||
? UrlHelper.toUrl(githubUrlOrHandle!, 'github') | ||
: null; | ||
|
||
String? get xLink => | ||
xUrlOrHandle != null ? UrlHelper.toUrl(xUrlOrHandle!, 'x') : null; | ||
|
||
String? get linkedinLink => linkedinUrlOrHandle != null | ||
? UrlHelper.toUrl(linkedinUrlOrHandle!, 'linkedin') | ||
: null; | ||
|
||
String get mdLink => | ||
'[${this.name}](https://github.com/martin-bertele/ftcon24eu/blob/main/Speakers.md#${this.name.toLowerCase().replaceAll(' ', '-')})'; | ||
|
||
Speaker copyWith({ | ||
String? name, | ||
String? bio, | ||
String? companyName, | ||
String? companyUrl, | ||
String? githubUrlOrHandle, | ||
String? xUrlOrHandle, | ||
String? linkedinUrlOrHandle, | ||
String? webUrl, | ||
}) { | ||
return Speaker( | ||
name: name ?? this.name, | ||
bio: bio ?? this.bio, | ||
companyName: companyName ?? this.companyName, | ||
companyUrl: companyUrl ?? this.companyUrl, | ||
githubUrlOrHandle: githubUrlOrHandle ?? this.githubUrlOrHandle, | ||
xUrlOrHandle: xUrlOrHandle ?? this.xUrlOrHandle, | ||
linkedinUrlOrHandle: linkedinUrlOrHandle ?? this.linkedinUrlOrHandle, | ||
webUrl: webUrl ?? this.webUrl, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import 'models.dart'; | ||
|
||
class Talk { | ||
final List<Speaker> speakers; | ||
final String title; | ||
final String? description; | ||
final List<Hyperlink>? resources; | ||
final List<Recommendation>? recommendations; | ||
final String? day; | ||
final String? time; | ||
final DateTime? startsAt; | ||
final DateTime? endsAt; | ||
final String? room; | ||
final String? format; | ||
final String? level; | ||
final String? videoUrl; | ||
final List<String>? topics; | ||
|
||
Talk({ | ||
required this.speakers, | ||
required this.title, | ||
this.description, | ||
this.resources, | ||
this.recommendations, | ||
this.day, | ||
this.time, | ||
this.startsAt, | ||
this.endsAt, | ||
this.room, | ||
this.format, | ||
this.level, | ||
this.videoUrl, | ||
this.topics, | ||
}); | ||
|
||
factory Talk.fromJson(Map<String, dynamic> json) => Talk( | ||
speakers: List<Speaker>.from( | ||
json['speakers'].map((model) => Speaker.fromJson(model))), | ||
title: json['title'], | ||
description: json['description'], | ||
resources: (json['resources'] as List<dynamic>?) | ||
?.map((r) => Hyperlink.fromJson(r)) | ||
.toList(), | ||
recommendations: (json['recommendations'] as List<dynamic>?) | ||
?.map((r) => Recommendation.fromJson(r)) | ||
.toList(), | ||
day: json['day'], | ||
time: json['time'], | ||
startsAt: json['startsAt'] != null | ||
? DateTime.parse(json['startsAt']).toLocal() | ||
: null, | ||
endsAt: json['endsAt'] != null | ||
? DateTime.parse(json['endsAt']).toLocal() | ||
: null, | ||
room: json['room'], | ||
format: json['format'], | ||
level: json['level'], | ||
videoUrl: json['videoUrl'], | ||
topics: List<String>.from(json['topics']), | ||
); | ||
|
||
String get tableRow { | ||
final titleColumn = this.videoUrl?.isNotEmpty == true | ||
? '[${this.title}](${this.videoUrl})' | ||
: this.title; | ||
final speakersColumn = this.speakers.map((s) => s.mdLink).join(', '); | ||
final resourcesColumn = this | ||
.resources | ||
?.where((r) => r.label != 'Slides/Blog/...') | ||
.map((r) => '[${r.label}](${r.url})') | ||
.join(', '); | ||
final recommendationsColumn = | ||
this.recommendations?.map((r) => '[${r.tool}](${r.url})').join('<br>'); | ||
|
||
return '| $titleColumn | $speakersColumn | $resourcesColumn | $recommendationsColumn |'; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import 'dart:convert'; | ||
import 'dart:io'; | ||
import 'models/models.dart'; | ||
|
||
Future<void> parseJsons( | ||
List<Talk> talks, | ||
List<Speaker> uniqueSpeakers, | ||
List<Company> uniqueCompanies, | ||
) async { | ||
const dataDir = 'talks'; | ||
final directory = Directory(dataDir); | ||
final files = await directory | ||
.list() | ||
.where((file) => file.path.endsWith('.json')) | ||
.toList(); | ||
|
||
for (var file in files) { | ||
final fileContent = await File(file.path).readAsString(); | ||
talks.add(Talk.fromJson(jsonDecode(fileContent))); | ||
} | ||
|
||
for (Talk talk in talks) { | ||
for (Speaker speaker in talk.speakers) { | ||
int existingIndex = | ||
uniqueSpeakers.indexWhere((s) => s.name == speaker.name); | ||
|
||
if (existingIndex > 0) { | ||
// A speaker with the same name exists, compare the filled data | ||
Speaker existingSpeaker = uniqueSpeakers[existingIndex]; | ||
uniqueSpeakers[existingIndex] = uniqueSpeakers[existingIndex].copyWith( | ||
companyName: existingSpeaker.companyName?.isEmpty == true | ||
? speaker.companyName | ||
: existingSpeaker.companyName, | ||
bio: existingSpeaker.bio?.isEmpty == true | ||
? speaker.bio | ||
: existingSpeaker.bio, | ||
companyUrl: existingSpeaker.companyUrl?.isEmpty == true | ||
? speaker.companyUrl | ||
: existingSpeaker.companyUrl, | ||
githubUrlOrHandle: existingSpeaker.githubUrlOrHandle?.isEmpty == true | ||
? speaker.githubUrlOrHandle | ||
: existingSpeaker.githubUrlOrHandle, | ||
xUrlOrHandle: existingSpeaker.xUrlOrHandle?.isEmpty == true | ||
? speaker.xUrlOrHandle | ||
: existingSpeaker.xUrlOrHandle, | ||
linkedinUrlOrHandle: | ||
existingSpeaker.linkedinUrlOrHandle?.isEmpty == true | ||
? speaker.linkedinUrlOrHandle | ||
: existingSpeaker.linkedinUrlOrHandle, | ||
webUrl: existingSpeaker.webUrl?.isEmpty == true | ||
? speaker.webUrl | ||
: existingSpeaker.webUrl, | ||
); | ||
} else { | ||
// No speaker with the same name exists, add the new speaker | ||
uniqueSpeakers.add(speaker); | ||
} | ||
|
||
int idx = | ||
uniqueCompanies.indexWhere((c) => c.name == speaker.companyName); | ||
if (idx < 0) { | ||
if (speaker.companyName != null && speaker.companyName!.isNotEmpty) | ||
uniqueCompanies.add(Company( | ||
name: speaker.companyName!, | ||
speakers: List.from(talk.speakers), | ||
)); | ||
} else { | ||
// add speaker to existing company | ||
uniqueCompanies[idx].speakers.add(speaker); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import 'dart:io'; | ||
import 'dart:convert'; | ||
import 'models/models.dart'; | ||
|
||
void writeAgenda(List<Talk> talks) async { | ||
final agendaContent = StringBuffer(); | ||
|
||
agendaContent.writeln('# Agenda\n\n'); | ||
|
||
// Define the agenda days | ||
const days = ["Wednesday", "Thursday", "Friday"]; | ||
|
||
for (var day in days) { | ||
// Add subheadline for each day | ||
agendaContent.writeln('## $day\n'); | ||
|
||
// Generate table headers | ||
agendaContent.writeln( | ||
'| Time & Room | Title | Speakers | Resources | Recommendations |'); | ||
agendaContent.writeln( | ||
'| ----------- | ----- | -------- | --------- | --------------- |'); | ||
|
||
// Filter talks by current day | ||
var filteredTalks = List.from(talks.where((talk) => talk.day == day)); | ||
filteredTalks.sort((a, b) { | ||
int compareTime = a.startsAt!.compareTo(b.startsAt!); | ||
if (compareTime != 0) return compareTime; | ||
const roomOrder = [ | ||
'Widget Way', | ||
'Async Area', | ||
'Dart Den', | ||
'Flutter Forest' | ||
]; | ||
return roomOrder.indexOf(a.room).compareTo(roomOrder.indexOf(b.room)); | ||
}); | ||
|
||
// Iterate over filtered talks to populate the table | ||
filteredTalks.forEach((talk) => agendaContent | ||
.writeln('| **${talk.time}**<br>*${talk.room}* ${talk.tableRow}')); | ||
|
||
// Add a newline for spacing between days | ||
agendaContent.writeln('\n'); | ||
} | ||
|
||
// Write the accumulated content to Agenda.md | ||
await File('Agenda.md').writeAsString(agendaContent.toString()); | ||
} |
Empty file.
Oops, something went wrong.