Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## VENV folders and files
bin
include
lib
lib*
__pycache__
pyvenv.cfg

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ http://flagsmashupbot.pythonanywhere.com/



![alt text](https://i.imgur.com/LSepqer.png)
![Twitter Screenshot](https://i.imgur.com/8SD4piZ.png)

https://twitter.com/FlagsMashupBot
-------------------------------------------------------

## Prerequisites
- Python3
- Pycairo's [required files in your machine](https://pycairo.readthedocs.io/en/latest/getting_started.html)
- Cairo's [required files in your machine](https://cairosvg.org/documentation/#installation)

### Clone the repo
```bash
Expand All @@ -22,7 +22,7 @@ git clone https://github.com/antooro/FlagsMashupBot
### Start a virtual environment
**LINUX/OSX**: Inside the repo folder
```bash
python -m ./ # starts the venv in the current folder
python3 -m venv ./ # starts the venv in the current folder
source bin/activate # On LINUX or OSX
.\Scripts\activate # ONLY Windows
```
Expand Down
Binary file modified countries.db
Binary file not shown.
168 changes: 70 additions & 98 deletions formatsvg.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
import requests
import random
from PIL import Image
from collections import Counter
from names import NameJoiner
from bs4 import BeautifulSoup
import itertools
import math
import os
import random
import shutil
import cairosvg
import sqlite3
import itertools
import math
from collections import Counter

import cairosvg
import requests
from PIL import Image
from bs4 import BeautifulSoup

from names import NameJoiner

API_URL = 'https://restcountries.com/v3.1'


class CountryMixer:
def __init__(self):
self.templateUrl = None
self.flags_info = None
self.svgText = None
self.template3Code = None
self.countries = None
self.second_country = None
self.first_country = None

def rgb2hex(self, color):
r, g, b = color
code = "#{:02x}{:02x}{:02x}".format(r, g, b)
Expand All @@ -26,7 +39,7 @@ def smallerHex(self, bigHex):

def getCountry(self, code):
for n in self.flags_info:
if n['alpha2Code'] == code:
if n['cca2'] == code:
country = n
print(country['name'])
return country
Expand All @@ -36,12 +49,10 @@ def getNeighbours(self):
while not hasCountries:
first_country = random.choice(self.flags_info)

country_flag_code = first_country['alpha3Code']
print(country_flag_code, first_country['borders'])
if len(first_country['borders']) > 0:
if 'borders' in first_country:
frontier = random.choice(first_country['borders'])
for flag_info in self.flags_info:
if flag_info['alpha3Code'] == frontier:
if flag_info['cca3'] == frontier:
second_country = flag_info

if first_country and second_country:
Expand All @@ -51,13 +62,13 @@ def getNeighbours(self):
self.second_country = second_country
self.countries = (self.first_country, self.second_country)
for country in self.countries:
self.downloadPNGFlag(country["alpha3Code"])
self.downloadPNGFlag(country['flags']['svg'], country["cca3"])

def updateDbWithBase(self, template):
conn = sqlite3.connect('countries.db')
c = conn.cursor()
first_country, second_country = sorted(
[self.first_country['alpha2Code'], self.second_country['alpha2Code']])
[self.first_country['cca2'], self.second_country['cca2']])

c.execute('update countries set base=(?) where first_country=(?) and second_country=(?) and base is null',
(template, first_country, second_country))
Expand All @@ -66,8 +77,7 @@ def updateDbWithBase(self, template):
def insertCountries(self):
conn = sqlite3.connect('countries.db')
c = conn.cursor()
first_country, second_country = sorted(
[self.first_country['alpha2Code'], self.second_country['alpha2Code']])
first_country, second_country = sorted([self.first_country['cca2'], self.second_country['cca2']])
print(first_country, second_country)
c.execute('insert into countries values (?,?,?)',
(first_country, second_country, None))
Expand All @@ -87,8 +97,8 @@ def checkMashupValid(self):
conn = sqlite3.connect('countries.db')
c = conn.cursor()
first_country, second_country = sorted(
[self.first_country['alpha2Code'], self.second_country['alpha2Code']])
if first_country == "NU" or second_country == "NU":
[self.first_country['cca2'], self.second_country['cca2']])
if "NU" in [first_country, second_country]: # why?
return False
print(first_country, second_country)
c.execute('select * from countries where first_country=? and second_country=?',
Expand All @@ -98,77 +108,64 @@ def checkMashupValid(self):
if len(rows) == 1 and rows[0][2]:
co = Counter(rows[0])
self.template3Code = co.most_common()[-1][0]
if self.template3Code == self.first_country['alpha2Code']:
self.template3Code = self.first_country['alpha3Code']
if self.template3Code == self.first_country['cca2']:
self.template3Code = self.first_country['cca3']
else:
self.template3Code = self.second_country['alpha3Code']
self.template3Code = self.second_country['cca3']
print(self.template3Code)
return True
elif len(rows) < 1:
self.template3Code = None

return True
else:
self.template3Code = None

return False
return len(rows) < 1

def getFullFlagsInfoJSON(self):
info = requests.get("https://restcountries.eu/rest/v2/all")
info = requests.get(f"{API_URL}/all")
if info.status_code != 200:
raise RuntimeError("Can't get full flags info")

return info.json()

def chooseRandomFlag(self, alreadyChoosen=None):

while True:
flag = random.choice(self.flags_info)
if flag['alpha3Code'] != alreadyChoosen:
if flag['cca3'] != alreadyChoosen:
return flag

def downloadPNGFlag(self, alpha3Code):
r = requests.get(
f"https://restcountries.eu/data/{alpha3Code.lower()}.svg")
print(alpha3Code)
cairosvg.svg2png(bytestring=r.text,
write_to=f'{alpha3Code.lower()}.png')
def downloadPNGFlag(self, url, alpha3Code):
r = requests.get(url)
cairosvg.svg2png(bytestring=r.text, write_to=f'{alpha3Code.lower()}.png')

def randomlyDownloadFlags(self):

self.first_country = self.chooseRandomFlag()
self.second_country = self.chooseRandomFlag()
self.countries = (self.first_country, self.second_country)

for country in self.countries:
self.downloadPNGFlag(country["alpha3Code"])
self.downloadPNGFlag(country['flags']['svg'], country["cca3"])

def getFlagsEmojis(self):
emojis = []

for country in self.countries:
country_alpha_code = country['alpha2Code']
emoji = (chr(
ord(country_alpha_code[0]) + 127397) + chr(ord(country_alpha_code[1]) + 127397))
country_alpha_code = country['cca2']
emoji = (chr(ord(country_alpha_code[0]) + 127397) + chr(ord(country_alpha_code[1]) + 127397))
emojis.append(emoji)

return emojis

def getFlagsSortedColors(self):

flagsSortedColors = []

for country in self.countries:
img = Image.open(f'{country["alpha3Code"].lower()}.png')
img = Image.open(f'{country["cca3"].lower()}.png')
width, height = img.size
limit = ((width * height) * .01)
colors = img.convert('RGBA').getcolors(
img.size[0] * img.size[1]) # this converts the mode to RGB
colors = sorted(colors, key=lambda x: x[0], reverse=True)
colors = [c for c in colors if c[1][3] != 0]

colorb1 = [self.rgb2hex(color[1][:3])
for color in colors[:5] if color[0] > limit]
colorb1 = [self.rgb2hex(color[1][:3]) for color in colors[:5] if color[0] > limit]

combinations = itertools.combinations(colorb1, 2)

Expand Down Expand Up @@ -202,16 +199,17 @@ def selectTemplateAndColors(self, nameColorList):
if random.randint(0, 2) == 0:
template, colors = colors, template

if self.isAlreadyDone(self.countries[template]["alpha2Code"], self.countries[colors]["alpha2Code"]):
if self.isAlreadyDone(self.countries[template]["cca2"], self.countries[colors]["cca2"]):
template, colors = colors, template

if self.first_country is not self.second_country:
self.updateDbWithBase(self.countries[template]["alpha2Code"])
self.updateDbWithBase(self.countries[template]["cca2"])

if not self.template3Code:
self.template3Code = self.countries[template]['alpha3Code']
templateSVG = requests.get(
f"https://restcountries.eu/data/{self.template3Code.lower()}.svg")
if not self.templateUrl or not self.template3Code:
self.templateUrl = self.countries[template]['flags']['svg']
self.template3Code = self.countries[template]['cca3']

templateSVG = requests.get(self.templateUrl)

for i in nameColorList:

Expand Down Expand Up @@ -278,18 +276,15 @@ def clean(self, text):

if differs:
print("They differ")
data = str(svg).replace("<html><body>",
"\n").replace("</body></html>", "")
text = data
text = str(svg).replace("<html><body>", "\n").replace("</body></html>", "")

return text

def changeColors(self, changes):
self.svgText = self.clean(self.svgText)
for new, old in changes.items():
self.svgText = self.svgText.replace(old, new.replace('#', 'ç'))
self.svgText = self.svgText.replace(
old.upper(), new.replace('#', 'ç'))
self.svgText = self.svgText.replace(old.upper(), new.replace('#', 'ç'))

for new, old in changes.items():
self.svgText = self.svgText.replace(
Expand All @@ -300,38 +295,18 @@ def changeColors(self, changes):
self.svgText = self.svgText.replace('ç', '#')

def calculateNames(self):
name1 = self.first_country['name']
name2 = self.second_country['name']

if "(" in name1:
p_temp = name1.split("(")
name1 = p_temp[1].replace(")", "") + " " + p_temp[0]

if "(" in name2:
p_temp = name2.split("(")
name2 = p_temp[1].replace(")", "") + " " + p_temp[0]
name1 = self.first_country['name']['common']
name2 = self.second_country['name']['common']

if "," in name1:
p_temp = name1.split(", ")
name1 = p_temp[1] + " " + p_temp[0]

if "," in name2:
p_temp = name2.split(", ")
name2 = p_temp[1] + " " + p_temp[0]

self.first_country['name'] = name1
self.second_country['name'] = name2
if name1 == name2:
return name1 + ' 2'

if len(name2.split()) > 1:
name = (" ".join(name2.split()[:-1]) + " " + name1.split()[-1])
return " ".join(name2.split()[:-1]) + " " + name1.split()[-1]
elif len(name1.split()) > 1:
name = (" ".join(name1.split()[:-1]) + " " + name2.split()[-1])
return " ".join(name1.split()[:-1]) + " " + name2.split()[-1]
else:
name = NameJoiner(
self.first_country['name'], self.second_country['name']).join()
if name1 == name2:
name = name1 + " 2"
return name
return NameJoiner(self.first_country['name']['common'], self.second_country['name']['common']).join()

def saveToPNG(self):
image = Image.open(f'{self.template3Code.lower()}.png')
Expand All @@ -347,7 +322,7 @@ def saveToPNG(self):
if fileSize < limit_kb:
uploaded = True
else:
bigger = bigger * 1.25
bigger *= 1.25

def mixFlags(self):

Expand All @@ -356,19 +331,16 @@ def mixFlags(self):
print(colorb1, len(colorb1))
print(colorb2, len(colorb2))

template, colors = self.selectTemplateAndColors(
[(0, colorb1), (1, colorb2)])
template, colors = self.selectTemplateAndColors([(0, colorb1), (1, colorb2)])
self.svgText = template
self.changeColors(colors)
self.saveToPNG()

def removePNGs(self):
i = 1
for country_data in self.countries:
for index, country_data in enumerate(self.countries, 1):
try:
filePath = f'{country_data["alpha3Code"].lower()}.png'
flagPath = f'flag{i}.png'
i = i + 1
filePath = f'{country_data["cca3"].lower()}.png'
flagPath = f'flag{index}.png'
shutil.move(filePath, flagPath)
except:
print("Unable to delete", filePath)
Expand All @@ -386,8 +358,8 @@ def manuallyDownloadFlags(self, alpha3CodeFlag1=None, alpha3CodeFlag2=None):

self.countries = (self.first_country, self.second_country)

self.downloadPNGFlag(self.first_country["alpha3Code"])
self.downloadPNGFlag(self.second_country["alpha3Code"])
self.downloadPNGFlag(self.first_country['flags']['svg'], self.first_country["cca3"])
self.downloadPNGFlag(self.second_country['flags']['svg'], self.second_country["cca3"])

def main(self):
self.flags_info = self.getFullFlagsInfoJSON()
Expand All @@ -405,13 +377,13 @@ def main(self):
self.insertCountries()
self.mixFlags()
print("Base is " + self.template3Code)
print(self.first_country['alpha3Code'],
self.second_country['alpha3Code'])
print(self.first_country['cca3'],
self.second_country['cca3'])
name = self.calculateNames()
print(name)

self.removePNGs()
return [self.first_country["name"], self.second_country["name"]], self.getFlagsEmojis(), name
return [self.first_country["name"]['common'], self.second_country["name"]['common']], self.getFlagsEmojis(), name


c = CountryMixer()
Expand Down
Loading