Skip to content
Snippets Groups Projects
Commit 67d01904 authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Merge branch '64-improve-generate-words-images-lists-fix-improve-code' into 'master'

Resolve "Improve generate words/images lists, fix/improve code"

Closes #64

See merge request !67
parents 9bba283b 5cf26823
No related branches found
No related tags found
1 merge request!67Resolve "Improve generate words/images lists, fix/improve code"
Pipeline #4856 passed
Showing
with 3392 additions and 3411 deletions
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
app.versionName=0.1.32
app.versionCode=56
app.versionName=0.1.33
app.versionCode=57
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Improve generate words/images lists, fix/improve relative code.
Amélioration de la génération des listes de mots et d'images. Correction du code correspondant.
class Word {
final String key;
final String text;
final List<String> images;
const Word({
required this.key,
required this.text,
required this.images,
});
Map<String, dynamic> toJson() {
return {
'key': this.key,
'text': this.text,
'images': this.images.toString(),
};
}
String toString() {
return this.toJson().toString();
}
}
import 'package:flutter/foundation.dart';
import 'package:wordguessing/models/word.dart';
class Data extends ChangeNotifier {
// Language
String _lang = '';
// randomization
Map _word = {};
List _otherWords = [];
List _images = [];
Word? _word;
List<Word> _otherWords = [];
List<Word> _images = [];
final int _recentWordsCount = 20;
List _recentWords = [];
List<String> _recentWordsKeys = [];
// game data
int _questionsCount = 0;
......@@ -23,37 +24,37 @@ class Data extends ChangeNotifier {
notifyListeners();
}
Map get word => _word;
Word? get word => _word;
set updateWord(Map value) {
_word = value;
if (value.containsKey('key') && value['key'] != '') {
_recentWords.insert(0, value['key']);
_recentWords = _recentWords.take(_recentWordsCount).toList();
set updateWord(Word? newWord) {
_word = newWord;
if ((newWord != null) && (newWord.key != '')) {
_recentWordsKeys.insert(0, newWord.key);
_recentWordsKeys = _recentWordsKeys.take(_recentWordsCount).toList();
}
notifyListeners();
}
bool isRecentlyPicked(String word) {
return _recentWords.contains(word);
return _recentWordsKeys.contains(word);
}
List get otherWords => _otherWords;
set updateOtherWords(List words) {
set updateOtherWords(List<Word> words) {
_otherWords = words;
notifyListeners();
}
List get images => _images;
List<Word> get images => _images;
set updateImages(List images) {
set updateImages(List<Word> images) {
_images = images;
notifyListeners();
}
void resetGame() {
_word = {};
_word = null;
_otherWords = [];
_images = [];
_questionsCount = 0;
......
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wordguessing/models/word.dart';
import 'package:wordguessing/utils/random_pick_words.dart';
import '../provider/data.dart';
import '../utils/random_pick_data.dart';
class GamePickImagePage extends StatelessWidget {
final int _countWords = 4;
final int _countImages = 1;
Future<void> startGame(Data myProvider, String lang) async {
await resetGame(myProvider);
......@@ -19,7 +19,7 @@ class GamePickImagePage extends StatelessWidget {
myProvider.updateQuestionsCount = 0;
myProvider.updateGoodAnswers = 0;
myProvider.updateWrongAnswers = 0;
myProvider.updateWord = {};
myProvider.updateWord = null;
myProvider.updateImages = [];
}
......@@ -29,30 +29,38 @@ class GamePickImagePage extends StatelessWidget {
}
Future<void> pickData(Data myProvider) async {
List words = [];
RandomPickData randomPickData;
Map word = {};
List<Word> words = [];
RandomPickWords randomPickWords;
Word? word;
int attempts = 0;
do {
randomPickData = RandomPickData();
await randomPickData.init(myProvider.lang, _countWords, _countImages);
randomPickWords = RandomPickWords();
await randomPickWords.init(myProvider.lang, _countWords);
if (randomPickData.words.isNotEmpty) {
words = randomPickData.words;
words = randomPickWords.words;
if (words.length > 0) {
word = words.take(1).toList()[0];
}
attempts++;
if ((words.length == _countWords) && !myProvider.isRecentlyPicked(word['key'])) {
myProvider.updateWord = word;
myProvider.updateImages = words;
if ((words.length == _countWords) && !myProvider.isRecentlyPicked(word.key)) {
myProvider.updateWord = word;
List<Word> images = [];
words.forEach((element) {
images.add(element);
});
myProvider.updateImages = images;
}
}
attempts++;
} while (myProvider.word != word && attempts < 10);
}
Future<void> checkWord(Data myProvider, word) async {
if (myProvider.word['key'] == word['key']) {
if (myProvider.word?.key == word.key) {
myProvider.updateGoodAnswers = myProvider.goodAnswers + 1;
nextWord(myProvider);
} else {
......@@ -122,14 +130,12 @@ class GamePickImagePage extends StatelessWidget {
);
}
Container _buildImageContainer(Data myProvider, Map word) {
Container _buildImageContainer(Data myProvider, Word word) {
double imageSize = 130;
String imageAsset = 'assets/placeholder.png';
if ((word['images'] != null) &&
(word['images'].length != 0) &&
(word['images'][0] != null)) {
imageAsset = 'assets/images/' + word['images'][0];
if ((word.images.length != 0)) {
imageAsset = 'assets/images/' + word.images[0];
}
return Container(
......@@ -158,13 +164,13 @@ class GamePickImagePage extends StatelessWidget {
}
Column _buildImageItemsBlock(Data myProvider) {
List words = myProvider.images;
List<Word> images = myProvider.images;
if (words.length != _countWords) {
if (images.length != _countWords) {
return Column();
}
words.sort((a, b) => a['key'].compareTo(b['key']));
images.sort((a, b) => a.key.compareTo(b.key));
return Column(
mainAxisSize: MainAxisSize.min,
......@@ -174,59 +180,49 @@ class GamePickImagePage extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildImageContainer(myProvider, words[0]),
_buildImageContainer(myProvider, words[1]),
_buildImageContainer(myProvider, images[0]),
_buildImageContainer(myProvider, images[1]),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildImageContainer(myProvider, words[2]),
_buildImageContainer(myProvider, words[3]),
_buildImageContainer(myProvider, images[2]),
_buildImageContainer(myProvider, images[3]),
],
)
],
);
}
Column _buildTextItemBlock(Data myProvider) {
Map word = myProvider.word;
Widget _buildTextItemBlock(Data myProvider) {
Word? word = myProvider.word;
if (word.isEmpty) {
return Column();
if (word == null) {
return const SizedBox.shrink();
}
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.all(2),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(6),
border: Border.all(
color: Colors.white,
width: 6,
),
),
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.all(15),
),
child: Text(
word.containsKey(myProvider.lang) ? word[myProvider.lang] : '',
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
onPressed: null,
return Container(
decoration: BoxDecoration(
color: Colors.blue.shade800,
borderRadius: BorderRadius.circular(6),
border: Border.all(
color: Colors.white,
width: 6,
),
),
child: Padding(
padding: EdgeInsets.all(12),
child: Text(
word.text,
style: TextStyle(
fontSize: 30,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
],
),
);
}
......@@ -276,7 +272,7 @@ class GamePickImagePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Data _myProvider = Provider.of<Data>(context);
Data myProvider = Provider.of<Data>(context);
Scaffold pageContent = Scaffold(
appBar: AppBar(
......@@ -284,7 +280,7 @@ class GamePickImagePage extends StatelessWidget {
actions: <Widget>[
IconButton(
icon: const Icon(Icons.loop),
onPressed: () => resetGame(_myProvider),
onPressed: () => resetGame(myProvider),
),
],
),
......@@ -295,13 +291,13 @@ class GamePickImagePage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
_buildTextItemBlock(_myProvider),
_buildTextItemBlock(myProvider),
SizedBox(height: 2),
((!_myProvider.word.containsKey('key')) || (_myProvider.word['key'] == ''))
? _buildStartGameBlock(_myProvider)
: _buildScoreContainer(_myProvider),
((myProvider.word == null) || (myProvider.word?.key == ''))
? _buildStartGameBlock(myProvider)
: _buildScoreContainer(myProvider),
SizedBox(height: 2),
_buildImageItemsBlock(_myProvider),
_buildImageItemsBlock(myProvider),
],
),
),
......
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:wordguessing/models/word.dart';
import 'package:wordguessing/utils/random_pick_words.dart';
import '../provider/data.dart';
import '../utils/random_pick_data.dart';
class GamePickWordPage extends StatelessWidget {
final int _countWords = 4;
......@@ -19,7 +20,7 @@ class GamePickWordPage extends StatelessWidget {
myProvider.updateQuestionsCount = 0;
myProvider.updateGoodAnswers = 0;
myProvider.updateWrongAnswers = 0;
myProvider.updateWord = {};
myProvider.updateWord = null;
myProvider.updateImages = [];
}
......@@ -29,26 +30,26 @@ class GamePickWordPage extends StatelessWidget {
}
Future<void> pickData(Data myProvider) async {
List words = [];
List images = [];
RandomPickData randomPickData;
Map word = {};
List<Word> words = [];
List<Word> images = [];
RandomPickWords randomPickWords;
Word word;
int attempts = 0;
do {
randomPickData = RandomPickData();
await randomPickData.init(myProvider.lang, _countWords, _countImages);
randomPickWords = RandomPickWords();
await randomPickWords.init(myProvider.lang, _countWords);
words = randomPickWords.words;
word = words.take(1).toList()[0];
images = [word];
if (randomPickData.words.isNotEmpty) {
words = randomPickData.words;
word = words.take(1).toList()[0];
images = word['images'];
}
attempts++;
if ((words.length == _countWords) &&
(images.length == _countImages) &&
!myProvider.isRecentlyPicked(word['key'])) {
if ((words.length >= _countWords) &&
// (images.length >= _countImages) &&
!myProvider.isRecentlyPicked(word.key)) {
myProvider.updateWord = word;
myProvider.updateOtherWords = words.skip(1).toList();
myProvider.updateImages = images;
......@@ -57,7 +58,7 @@ class GamePickWordPage extends StatelessWidget {
}
Future<void> checkWord(Data myProvider, word) async {
if (myProvider.word['key'] == word['key']) {
if (myProvider.word?.key == word.key) {
myProvider.updateGoodAnswers = myProvider.goodAnswers + 1;
nextWord(myProvider);
} else {
......@@ -152,8 +153,8 @@ class GamePickWordPage extends StatelessWidget {
);
}
Column _buildImageItemsBlock(List images) {
if (images.length != _countImages) {
Column _buildImageItemsBlock(Word? currentWord) {
if ((currentWord?.images.length ?? 0) < _countImages) {
return Column();
}
......@@ -165,23 +166,23 @@ class GamePickWordPage extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildImageContainer(images[0]),
_buildImageContainer(images[1]),
_buildImageContainer(currentWord?.images[0] ?? ''),
_buildImageContainer(currentWord?.images[1] ?? ''),
],
),
Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
_buildImageContainer(images[2]),
_buildImageContainer(images[3]),
_buildImageContainer(currentWord?.images[2] ?? ''),
_buildImageContainer(currentWord?.images[3] ?? ''),
],
)
],
);
}
Container _buildTextContainer(Data myProvider, Map word) {
Container _buildTextContainer(Data myProvider, Word word) {
return Container(
margin: EdgeInsets.all(2),
decoration: BoxDecoration(
......@@ -197,7 +198,7 @@ class GamePickWordPage extends StatelessWidget {
padding: EdgeInsets.all(15),
),
child: Text(
word.containsKey(myProvider.lang) ? word[myProvider.lang] : '',
word.text,
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.w600,
......@@ -212,10 +213,10 @@ class GamePickWordPage extends StatelessWidget {
}
Column _buildTextItemsBlock(Data myProvider) {
Map word = myProvider.word;
Word? word = myProvider.word;
List otherWords = myProvider.otherWords;
if ((word.isEmpty) || (otherWords.length != (_countWords - 1))) {
if ((word == null) || (otherWords.length != (_countWords - 1))) {
return Column();
}
......@@ -226,7 +227,7 @@ class GamePickWordPage extends StatelessWidget {
otherWords.length > 2 ? otherWords[2] : null,
];
words.sort((a, b) => a['key'].compareTo(b['key']));
words.sort((a, b) => a.key.compareTo(b.key));
return Column(
mainAxisSize: MainAxisSize.min,
......@@ -301,7 +302,7 @@ class GamePickWordPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
Data _myProvider = Provider.of<Data>(context);
Data myProvider = Provider.of<Data>(context);
Scaffold pageContent = Scaffold(
appBar: AppBar(
......@@ -309,7 +310,7 @@ class GamePickWordPage extends StatelessWidget {
actions: <Widget>[
IconButton(
icon: const Icon(Icons.loop),
onPressed: () => resetGame(_myProvider),
onPressed: () => resetGame(myProvider),
),
],
),
......@@ -320,13 +321,15 @@ class GamePickWordPage extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
_buildImageItemsBlock(_myProvider.images),
(myProvider.images.length != 0)
? _buildImageItemsBlock(myProvider.images[0])
: SizedBox.shrink(),
SizedBox(height: 2),
((!_myProvider.word.containsKey('key')) || (_myProvider.word['key'] == ''))
? _buildStartGameBlock(_myProvider)
: _buildScoreContainer(_myProvider),
((myProvider.word == null) || (myProvider.word?.key == ''))
? _buildStartGameBlock(myProvider)
: _buildScoreContainer(myProvider),
SizedBox(height: 2),
_buildTextItemsBlock(_myProvider),
_buildTextItemsBlock(myProvider),
],
),
),
......
......@@ -11,14 +11,14 @@ class Home extends StatelessWidget {
myProvider.updateQuestionsCount = 0;
myProvider.updateGoodAnswers = 0;
myProvider.updateWrongAnswers = 0;
myProvider.updateWord = {};
myProvider.updateWord = null;
myProvider.updateOtherWords = [];
myProvider.updateImages = [];
}
@override
Widget build(BuildContext context) {
Data _myProvider = Provider.of<Data>(context);
Data myProvider = Provider.of<Data>(context);
Container _buildMenuItemContainer(String code, Color color) {
double imageSize = 150;
......@@ -42,7 +42,7 @@ class Home extends StatelessWidget {
fit: BoxFit.fill,
),
onTap: () {
resetGame(_myProvider);
resetGame(myProvider);
Navigator.pushNamed(
context,
'/' + code,
......
import 'dart:async';
import 'random_pick_word.dart';
import 'random_pick_image.dart';
class RandomPickData {
RandomPickData();
List _words = [];
init(String lang, int wordsCount, int imagesPerWordCount) async {
_words = List.filled(wordsCount, []);
await getWordsAndImages(lang, wordsCount, imagesPerWordCount);
}
Future<void> getWordsAndImages(String lang, int wordsCount, int imagesPerWordCount) async {
RandomPickWord randomPickWord;
RandomPickImage randomPickImage;
List pickedWords = [];
randomPickWord = RandomPickWord();
await randomPickWord.init(lang, wordsCount);
if (randomPickWord.words.isNotEmpty) {
pickedWords = randomPickWord.words;
for (var i = 0; i < pickedWords.length; i++) {
Map word = pickedWords[i];
randomPickImage = RandomPickImage();
await randomPickImage.init(word['key'], imagesPerWordCount);
if (randomPickImage.images.isNotEmpty) {
pickedWords[i]['images'] = randomPickImage.images;
}
}
}
_words = pickedWords;
}
List get words => _words;
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
class RandomPickImage {
RandomPickImage();
List _images = [];
init(String word, int count) async {
_images = List.filled(count, []);
await imageFromLocalFile(word, count);
}
Future<void> imageFromLocalFile(String word, int count) async {
// Get all images for this word
List imageList = [];
try {
String jsonString = await rootBundle.loadString('assets/assets_images.json');
final jsonResponse = await json.decode(jsonString);
imageList = jsonResponse['images'][word];
} catch (e) {
print("$e");
}
// Check we have enough images
if (imageList.length < count) {
print('Not enough images in list for word "' + word + '".');
_images = [];
} else {
// Randomize images list
imageList.shuffle();
// Pick first images from shuffled list
_images = imageList.take(count).toList();
}
}
List get images => _images;
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
class RandomPickWord {
RandomPickWord();
List _words = [];
init(String lang, int count) async {
_words = List.filled(count, []);
await wordFromLocalFile(lang, count);
}
Future<void> wordFromLocalFile(String lang, int count) async {
// Get global words list
List wordList = [];
try {
String jsonString = await rootBundle.loadString('assets/files/words.json');
final jsonResponse = await json.decode(jsonString);
wordList = jsonResponse['words'];
} catch (e) {
print("$e");
}
// Check we have enough words
if (wordList.length < count) {
print('Not enough words in list.');
_words = [];
} else {
// Remove empty words
wordList.removeWhere((w) => ((w.containsKey(lang) == false) || (w[lang] == '')));
// Randomize words list
wordList.shuffle();
// Pick first words from shuffled list
_words = wordList.take(count).toList();
}
}
List get words => _words;
}
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:wordguessing/models/word.dart';
class RandomPickWords {
RandomPickWords();
List<Word> _words = [];
init(String lang, int count) async {
await wordsFromLocalFile(lang, count);
}
Future<void> wordsFromLocalFile(String lang, int count) async {
List<Word> wordList = [];
try {
String jsonString = await rootBundle.loadString('assets/words.json');
final jsonResponse = await json.decode(jsonString);
Map<String, dynamic> wordsMap = jsonResponse['words'] as Map<String, dynamic>;
wordsMap.forEach((key, data) {
List<String> images = [];
(data['images'] as List<dynamic>).forEach((image) {
images.add(image as String);
});
images.shuffle();
if (images.length != 0) {
wordList.add(Word(
key: key,
text: data[lang] ?? '',
images: images,
));
}
});
} catch (e) {
print("$e");
}
// Check we have enough words
if (wordList.length < count) {
print('Not enough words in list.');
}
// Remove empty words
wordList.removeWhere((word) => (word.text == ''));
// Randomize words list
wordList.shuffle();
// Pick first words from shuffled list
_words = wordList.take(count).toList();
}
List<Word> get words => _words;
}
name: wordguessing
description: A wordguessing game application.
publish_to: 'none'
version: 0.1.32+56
version: 0.1.33+57
environment:
sdk: '^3.0.0'
......@@ -15,8 +15,7 @@ dependencies:
flutter:
uses-material-design: true
assets:
- assets/assets_images.json
- assets/files/
- assets/words.json
- assets/images/
- assets/menu/
- assets/placeholder.png
......@@ -20,7 +20,7 @@ TYPE="images"
OFFSET=0
BASE_URL="https://api.qwant.com/api/search/${TYPE}"
WORDS_LIST="$(cat "${INPUT_WORDS_LIST}" | grep -E '\"key\": \"[A-Z\-]+\",$' | cut -d'"' -f4 | sort | uniq | sort -R)"
WORDS_LIST="$(cat "${INPUT_WORDS_LIST}" | grep -E '\"fr\": \"[A-Z\-]+\",$' | cut -d'"' -f4 | sort | uniq | sort -R)"
while read -r KEYWORD; do
if [[ -n "${KEYWORD}" ]]; then
echo "KEYWORD: ${KEYWORD}"
......@@ -36,6 +36,7 @@ while read -r KEYWORD; do
# Get QWANT API query from keyword
QUERY="$(echo "${QUERY_STRING}" | tr "A-Z" "a-z" | sed 's| |%20|g')"
QUERY_URL="${BASE_URL}?count=${COUNT_BY_WEYWORD_VARIANT}&q=${QUERY}&t=${TYPE}&safesearch=1&offset=${OFFSET}&locale=${LANG}&uiv=4"
# echo "QUERY_URL: ${QUERY_URL}"
# Get QWANT thumbnails urls from keyword
URL_LIST="$(curl "${QUERY_URL}" \
......@@ -44,6 +45,10 @@ while read -r KEYWORD; do
--compressed \
| jq | grep "media_preview" | cut -d'"' -f4 | sed 's|^//||g')"
if [[ -z "${URL_LIST}" ]]; then
echo " No image found..."
fi
while read -r URL; do
if [[ -n "${URL}" ]]; then
HASH="$(echo "${URL}" | md5sum | awk '{print $1}')"
......
......@@ -4,8 +4,8 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
IMAGES_CACHE_FOLDER="${CURRENT_DIR}/cache"
IMAGES_DOWNLOAD_FOLDER="${CURRENT_DIR}/cache/download"
IMAGES_SELECTED_FOLDER="${CURRENT_DIR}/cache/download"
IMAGES_DOWNLOAD_FOLDER="${IMAGES_CACHE_FOLDER}/download"
IMAGES_SELECTED_FOLDER="${IMAGES_CACHE_FOLDER}/selected"
# delete empty/temp files
find "${IMAGES_CACHE_FOLDER}" -type f -name "*.png" -empty -exec rm {} \;
......@@ -13,7 +13,7 @@ find "${IMAGES_CACHE_FOLDER}" -type f -name "*.tmp*" -exec rm {} \;
find "${IMAGES_CACHE_FOLDER}" -type d -empty -exec rm -rf {} \;
# copy missing files from "download" to "selected"
rsync --ignore-existing -raz --progress "${IMAGES_DOWNLOAD_FOLDER}/*" "${IMAGES_SELECTED_FOLDER}"
rsync --ignore-existing -raz --progress ${IMAGES_DOWNLOAD_FOLDER}/* "${IMAGES_SELECTED_FOLDER}"
echo "done: copy files from download to selected."
echo "please remove unwanted files from selected folders."
......@@ -5,57 +5,82 @@ command -v jq >/dev/null 2>&1 || { echo >&2 "I require jq (json parser) but it's
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"
BASE_DIR="$(dirname "${CURRENT_DIR}")"
# CSV source file for words
SOURCE_CSV_FILE="${CURRENT_DIR}/words.csv"
ASSETS_BASE_FOLDER="${BASE_DIR}/assets"
IMAGES_ASSETS_FOLDER="${ASSETS_BASE_FOLDER}/images"
OUTPUT_ASSETS_FILE="${ASSETS_BASE_FOLDER}/assets_images.json"
touch "${OUTPUT_ASSETS_FILE}"
OUTPUT_WORDS_LIST="${ASSETS_BASE_FOLDER}/words.json"
touch "${OUTPUT_WORDS_LIST}"
TARGET_IMAGES_ASSETS_FOLDER="${ASSETS_BASE_FOLDER}/images"
IMAGES_CACHE_FOLDER="${CURRENT_DIR}/cache"
IMAGES_OPTIMIZED_FOLDER="${IMAGES_CACHE_FOLDER}/optimized"
SOURCE_IMAGES_OPTIMIZED_FOLDER="${IMAGES_CACHE_FOLDER}/optimized"
echo "Cleaning empty/temp files..."
find "${IMAGES_OPTIMIZED_FOLDER}" -type f -name "*.png" -empty -exec rm {} \;
find "${IMAGES_OPTIMIZED_FOLDER}" -type f -name "*.tmp*" -exec rm {} \;
find "${IMAGES_OPTIMIZED_FOLDER}" -type d -empty -exec rm -rf {} \;
find "${SOURCE_IMAGES_OPTIMIZED_FOLDER}" -type f -name "*.png" -empty -exec rm {} \;
find "${SOURCE_IMAGES_OPTIMIZED_FOLDER}" -type f -name "*.tmp*" -exec rm {} \;
find "${SOURCE_IMAGES_OPTIMIZED_FOLDER}" -type d -empty -exec rm -rf {} \;
echo "Cleaning existing assets..."
find "${IMAGES_ASSETS_FOLDER}" -type f -name "*.png" -exec rm {} \;
echo "Building assets json file..."
FILES="$(find "${IMAGES_OPTIMIZED_FOLDER}" -type f -name "*.png" | sed "s|^${IMAGES_OPTIMIZED_FOLDER}/||g" | sort)"
KEYWORDS="$(echo "${FILES}" | cut -d'/' -f1 | sort | uniq)"
OUTPUT_ASSETS_FILE_TMP="${OUTPUT_ASSETS_FILE}.tmp"
echo "{" > "${OUTPUT_ASSETS_FILE_TMP}"
echo " \"images\": {" >> "${OUTPUT_ASSETS_FILE_TMP}"
FIRST_KEYWORD=1
while read -r KEYWORD; do
if [[ -n "${KEYWORD}" ]]; then
echo "- ${KEYWORD}"
if [[ ${FIRST_KEYWORD} -eq 0 ]]; then
echo " ," >> "${OUTPUT_ASSETS_FILE_TMP}"
find "${TARGET_IMAGES_ASSETS_FOLDER}" -type f -name "*.png" -exec rm {} \;
echo "Building words/images assets json file..."
# Existing images in optimized folder
FILES="$(find "${SOURCE_IMAGES_OPTIMIZED_FOLDER}" -type f -name "*.png" | sed "s|^${SOURCE_IMAGES_OPTIMIZED_FOLDER}/||g" | sort)"
OUTPUT_WORDS_LIST_TMP="${OUTPUT_WORDS_LIST}.tmp"
echo "{" > "${OUTPUT_WORDS_LIST_TMP}"
echo " \"words\": {" >> "${OUTPUT_WORDS_LIST_TMP}"
FIRST_WORD=1
while read -r LINE; do
if [[ -n "${LINE}" ]]; then
echo "- ${LINE}"
WORD_FR="$(echo "${LINE}" | cut -d';' -f1)"
WORD_EN="$(echo "${LINE}" | cut -d';' -f2)"
KEY="$(echo "${LINE}" | md5sum | awk '{print $1;}')"
if [[ ${FIRST_WORD} -eq 0 ]]; then
echo " ," >> "${OUTPUT_WORDS_LIST_TMP}"
fi
echo " \"${KEY}\": {" >> "${OUTPUT_WORDS_LIST_TMP}"
echo " \"fr\": \"${WORD_FR}\"," >> "${OUTPUT_WORDS_LIST_TMP}"
echo " \"en\": \"${WORD_EN}\"," >> "${OUTPUT_WORDS_LIST_TMP}"
echo " \"images\": [" >> "${OUTPUT_WORDS_LIST_TMP}"
FOLDER_KEY="${WORD_FR}"
FILES_FOR_THIS_WORD="$(echo "${FILES}" | grep -E "^${FOLDER_KEY}/")"
if [[ -n "${FILES_FOR_THIS_WORD}" ]]; then
FIRST_FILE=1
while read -r FILE; do
if [[ ${FIRST_FILE} -eq 0 ]]; then
echo " ," >> "${OUTPUT_WORDS_LIST_TMP}"
fi
echo " \"$(echo "${FILE}" | sed "s|${FOLDER_KEY}/||g")\"" >> "${OUTPUT_WORDS_LIST_TMP}"
FIRST_FILE=0
cp -f "${SOURCE_IMAGES_OPTIMIZED_FOLDER}/${FILE}" "${TARGET_IMAGES_ASSETS_FOLDER}"
done < <(echo "${FILES_FOR_THIS_WORD}")
else
echo "No image found for ${KEY} / ${FOLDER_KEY}"
fi
echo " \"${KEYWORD}\": [" >> "${OUTPUT_ASSETS_FILE_TMP}"
FILES_KEYWORD="$(echo "${FILES}" | grep -e "^${KEYWORD}/")"
FIRST_FILE=1
while read -r FILE; do
if [[ ${FIRST_FILE} -eq 0 ]]; then
echo " ," >> "${OUTPUT_ASSETS_FILE_TMP}"
fi
echo " \"$(echo "${FILE}" | sed "s|${KEYWORD}/||g")\"" >> "${OUTPUT_ASSETS_FILE_TMP}"
FIRST_FILE=0
cp -f "${IMAGES_OPTIMIZED_FOLDER}/${FILE}" "${IMAGES_ASSETS_FOLDER}"
done < <(echo "${FILES_KEYWORD}")
echo " ]" >> "${OUTPUT_ASSETS_FILE_TMP}"
FIRST_KEYWORD=0
echo " ]" >> "${OUTPUT_WORDS_LIST_TMP}"
echo " }" >> "${OUTPUT_WORDS_LIST_TMP}"
FIRST_WORD=0
fi
done < <(echo "${KEYWORDS}")
echo " }" >> "${OUTPUT_ASSETS_FILE_TMP}"
echo "}" >> "${OUTPUT_ASSETS_FILE_TMP}"
done < <(cat "${SOURCE_CSV_FILE}" | sort | uniq)
echo " }" >> "${OUTPUT_WORDS_LIST_TMP}"
echo "}" >> "${OUTPUT_WORDS_LIST_TMP}"
# Format json
cat "${OUTPUT_ASSETS_FILE_TMP}" | jq > "${OUTPUT_ASSETS_FILE}"
rm "${OUTPUT_ASSETS_FILE_TMP}"
cat "${OUTPUT_WORDS_LIST_TMP}" | jq > "${OUTPUT_WORDS_LIST}"
rm "${OUTPUT_WORDS_LIST_TMP}"
echo "done."
ABEILLE;BEE
AIGUILLE;NEEDLE
ALLUMETTE;MATCH
AMBULANCE;AMBULANCE
AMPOULE;BULB
ANANAS;PINEAPPLE
AQUARIUM;AQUARIUM
ARAIGNÉE;SPIDER
ARBRE;TREE
ARMOIRE;CABINET
ARROSOIR;WATERING CAN
ASPERGE;ASPARGUS
ASPIRATEUR;VACUUM CLEANER
AUBERGINE;EGGPLANT
AUTRUCHE;OSTRICH
AVION;AIRPLANE
BALAI;BROOM
BALANÇOIRE;SWING
BALEINE;WHALE
BALLON;BALLOON
BANANE;BANANA
BASSINE;BASIN
BATEAU;BOAT
BAVOIR;BIB
BÉBÉ;BABY
BERCEAU;CRADLE
BEURRE;BUTTER
BIBERON;BABY BOTTLE
BISCUIT;COOKIE
BONBON;CANDY
BONNET;CAP
BOTTE;BOOT
BOUCHON;CORK
BOUGIE;CANDLE
BOUQUET;BUNCH
BOUTEILLE;BOTTLE
BROSSE;BRUSH
BROUETTE;WHEELBARROW
BÛCHE;LOG
CACTUS;CACTUS
CAFÉ;COFFEE
CAFETIÈRE;COFFEE MAKER
CAHIER;NOTEBOOK
CAMION;TRUCK
CANARD;DUCK
CAROTTE;CARROT
CARTABLE;BINDER
CASQUE;HELMET
CASQUETTE;CAP
CASSEROLE;PAN
CASTOR;BEAVER
CERF-VOLANT;KITE
CHAISE;CHAIR
CHAMPIGNON;MUSHROOM
CHATEAU;CASTLE
CHAUSSETTE;SOCK
CHAUSSURE;SHOE
CHEMINÉE;CHIMNEY
CHEMISE;SHIRT
CHEVAL;HORSE
CINTRE;HANGER
CISEAUX;SCISSORS
CITRON;LEMON
CITROUILLE;PUMPKIN
COCCINELLE;LADYBUG
COCOTTE-MINUTE;PRESSURE COOKER
COLLIER;NECKLACE
CONCOMBRE;CUCUMBER
CONFITURE;JAM
COQ;ROOSTER
COQUELICOT;POPPY
CORBEAU;CROW
CORDE;ROPE
CORNICHON;PICKLE
CRABE;CRAB
CRAYON;PENCIL
CROCODILE;CROCODILE
CULOTTE;PANTIES
DAUPHIN;DOLPHIN
DINOSAURE;DINOSAUR
DROMADAIRE;DROMEDARY
ÉCHELLE;LADDER
ÉCUREUIL;SQUIRREL
ÉLÉPHANT;ELEPHANT
ESCALIER;STAIRCASE
ESCARGOT;SNAIL
ÉTOILE;STAR
ÉVIER;SINK
FANTÔME;GHOST
FENÊTRE;WINDOW
FLEUR;FLOWER
FLÛTE;FLUTE
FOURCHETTE;FORK
FOURMI;ANT
FRAISE;STRAWBERRY
FRAMBOISE;RASPBERRY
FROMAGE;CHEESE
FUSÉE;ROCKET
GANT;GLOVE
GILET;VEST
GOMME;ERASER
GOURDE;FLASK
GRENOUILLE;FROG
GRILLE-PAIN;TOASTER
GUÊPE;WASP
GUITARE;GUITAR
HARMONICA;HARMONICA
HÉLICOPTÈRE;HELICOPTER
HIPPOCAMPE;SEAHORSE
HIPPOPOTAME;HIPPOPOTAMUS
JAMBON;HAM
JOURNAL;JOURNAL
JUPE;SKIRT
KANGOUROU;KANGAROO
KAYAK;KAYAK
KIWI;KIWI
LAIT;MILK
LAMPE;LAMP
LAPIN;RABBIT
LAVE-LINGE;WASHING MACHINE
LIBELLULE;DRAGONFLY
LICORNE;UNICORN
LION;LION
LIT;BED
LITIÈRE;LITTER
LIVRE;BOOK
LOUP;WOLF
LUNE;MOON
LUNETTES;GLASSES
MAISON;HOUSE
MARTEAU;HAMMER
MÉSANGE;TITMOUSE
MÉTRO;METRO
MICRO;MICROPHONE
MOTO;MOTORCYCLE
MOUCHE;FLY
MOUTON;SHEEP
NOEUD;KNOT
NOISETTE;HAZELNUT
OEUF;EGG
OIE;GOOSE
ORAGE;THUNDERSTORM
ORCHESTRE;ORCHESTRA
ORDINATEUR;COMPUTER
OREILLER;PILLOW
OURS;BEAR
PAIN;BREAD
PANDA;PANDA
PANTALON;PANTS
PAPILLON;BUTTERFLY
PAQUEBOT;LINER
PARAPLUIE;UMBRELLA
PASSOIRE;COLANDER
PÂTES;PASTA
PÊCHE;FISHING
PEIGNE;COMB
PELLE;SHOVEL
PELOTE;BALL OF WHOOL
PELUCHE;PLUSH
PENDULE;CLOCK
PÉNICHE;HOUSEBOAT
PERCEUSE;DRILL
PERLES;BEADS
PERROQUET;PARROT
PIANO;PIANO
PIGEON;PIGEON
PISCINE;POOL
PIVERT;WOODPECKER
PIZZA;PIZZA
PLAGE;BEACH
POIRE;PEAR
POISSON;FISH
POMME;APPLE
POMME-DE-TERRE;POTATO
POMPIER;FIREFIGHTER
POUBELLE;TRASH CAN
POULET;CHICKEN
POUPÉE;DOLL
POUSSETTE;STROLLER
POUSSIN;CHICK
PUZZLE;PUZZLE
PYJAMA;PYJAMAS
RADIS;RADIS
RAQUETTE;RACKET
RÂTEAU;RAKE
RENARD;FOX
REQUIN;SHARK
RÉVEIL;ALARM CLOCK
RHINOCÉROS;RHINOCEROS
RIVIÈRE;RIVER
ROBINET;FAUCET
ROSE;ROSE
SAC À DOS;BACKPACK
SAC;BAG
SALADE;SALAD
SANDALE;SANDAL
SANDWICH;SANDWICH
SANGLIER;BOAR
SAUCISSE;SAUSAGE
SAUCISSON;SAUSAGE
SAUTERELLE;GRASSHOPPER
SAVON;SOAP
SCIE;SAW
SEAU;BUCKET
SERPENT;SNAKE
SINGE;MONKEY
SOLEIL;SUN
SOUPE;SOUP
SOUS-MARIN;SUBMARINE
STADE;STADIUM
STATUE;STATUE
STYLO;PEN
SUCRE;SUGAR
TABOURET;STOOL
TACHE;SPOT
TAILLE-CRAYON;PENCIL SHARPENER
TAPIS;CARPET
TARTINE;TARTINE
TASSE;CUP
TÉLÉPHONE;TELEPHONE
TÉLÉVISION;TELEVISION
THERMOMÈTRE;THERMOMETER
TIRE-BOUCHON;CORKSCREW
TIROIR;DRAWER
TOBOGGAN;SLIDE
TONDEUSE;LAWNMOWER
TORCHON;TEA TOWEL
TORTUE;TURTLE
TOURNEVIS;SCREWDRIVER
TRACTEUR;TRACTOR
TRAIN;TRAIN
TROMPETTE;TRUMPET
TULIPE;TULIP
VACHE;COW
VALISE;SUITCASE
VASE;VASE
VÉLO;BIKE
VIOLON;VIOLIN
VOILIER;SAILBOAT
VOITURE;CAR
YAOURT;YOGURT
ZÈBRE;ZEBRA
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment