promitheas

joined 2 years ago
[–] promitheas@programming.dev 0 points 4 days ago

Dragged in by the US. One more reason to cut ties and go our separate ways.

[–] promitheas@programming.dev 0 points 4 days ago* (last edited 4 days ago) (2 children)

Maybe don’t insult the people who want to be your ally, or you’ll find yourself without any.

Are... Are you serious right now? You tell me this, after everything the orange has done and said? Some would consider it a bit too late to for that, the alliance has ended, if not officially in all other aspects, and you're the ones who've destroyed it. How can we ever trust you again?

Oh right, I guess Europe has never needed outside help with a fascist takeover

Don't play the good guy, you were profiting from both sides before officially joining, and once you joined it had no effect on your own fascism. Don't forget that prior to WW2, American Fascism/Racism was too extreme even for the Nazis, so they (the Nazis) deliberately toned their versions down a bit.

[–] promitheas@programming.dev 4 points 4 days ago

Having to spend time around people I dont care about but have to pretend I do. Also my birthday is soon after, which overall makes the season depressing.

[–] promitheas@programming.dev 1 points 1 week ago* (last edited 1 week ago)

A~~merica~~n ~~Whiskey Production H~~a ~~s Plummeted to a New~~ L~~ow~~

[–] promitheas@programming.dev 7 points 1 week ago

Semi related, but check out based.cooking for community provided recipes, with just ingredients+steps to cook.

[–] promitheas@programming.dev 16 points 1 week ago

Its not just that, directly. They also seem to be working for fossil fuel companies, amongst other things that make me have a feeling that they're goal is not to report news accurately but to push an agenda, which I doubt the people in this community subscribe to.

 

Ive noticed several posts here linking to politico articles, which I find strange for this community given their history and affiliations.

To everyone reading, just give the wiki page on them a read, follow the references cited in it, and make up your own mind on whether you want to trust it as a source for EU news.

To everyone who posts their articles in here, I hope its just because you weren't aware of all this, rather than anything else.

[–] promitheas@programming.dev 28 points 2 weeks ago* (last edited 2 weeks ago)

Also, if anyone suggests Electron or anything involving a browser, I will find them and remove one electron from each atom of theirs, turning them into smoke.

This made me laugh, it was so unexpected xD

Also, while its not an answer for your question, look up ncurses if you dont know it. It might be a middle ground for your future projects, if you prefer staying in the terminal but having a UI.

[–] promitheas@programming.dev 3 points 2 weeks ago

Yea haha, with the # and everything xD

[–] promitheas@programming.dev 4 points 2 weeks ago (2 children)

No way, thats exactly what i named my dads wifi when i set it up for him 😂

[–] promitheas@programming.dev 1 points 2 weeks ago

Nope, still getting stuck in a captcha loop. It may be my strict browser privacy settings. I tried the wayback machine but they don't seem to have archived this article yet

[–] promitheas@programming.dev 1 points 2 weeks ago

No worries, and thanks

 

Hello everyone!

I won't drag the post out too much since most of the info is already in the title, but I would love to hear some suggestions for some children's books to help me develop comfort with, and vocabulary in Dutch.

In terms of my level with the language, I have been doing some Duolingo for over 3 years, but I really started learning and understanding rules and such a couple months ago when I started online lessons.

Thanks in advance!

Edit: A couple people suggested Annie M.G. Schmidt so I looked at the first book in the Jip en Janneke books, but it seems that its too advanced for my level. I'll need to work my way up to that slowly. In the meantime, any suggestions for books aimed more towards 2-3 year olds? I feel like that would be more my current vocabulary level, and I can work my way up from there. Thanks

 

Hello guys.

I'm trying to learn some more KiCAD and general electronics design from scratch by continuing my thesis project after I've submitted it and its all done, but by taking it to the next step and actually getting a PCB and soldering everything on. This is to get experience through the entire process from design to assembly.

Where I'm stuck is at creating the footprints for my components. I've watched a bunch of videos about the topic, but they all seem to be for boards with no header pins attached to them, or for pins that are vertical (perpendicular to the actual board). The two boards I have are breakout boards for a DS3231 RTC and an HM-10 BLE module, and they both have right-angle male header pins sticking out, which obviously made prototyping on a breadboard really easy, but I'm struggling with converting them to PCB.

Here are some photos to make it clearer:

HM-10:

DS3231:

I know one of my options is to desolder the right-angle header pins and add straight pins to them, but I'd like to avoid that so that I can easily use them in any future projects by simply disconnecting them from the eventual PCB and using them in a breadboard.

As such, I know that I would like there to be female headers on the final PCB, and ideally the female headers will also be at a right-angle so that the final PCB is a little more compact and there aren't just some boards sticking out from it.

So, after getting some measurements with my calipers, how can I translate them into the KiCAD footprint editor knowing the footprint should include the female right-angle header pins (which will of course extend the length of the modules beyond what I have currently measured), and also take their height into account so that they don't have any obstacles between them and the PCB as they are laying parallel to it?

I hope I made myself clear enough, but if not please feel free to ask me for any clarification.

Thanks in advance for any replies :)

 

Hello guys, my question is basically in the title. I would really like to be able to have the parameter names included when I cursor over a function and open the 'hover' window to show basic info about it. Currently it only shows me the expected types, which while still useful I feel is only a piece of the puzzle when working either with a new library, or a codebase you're not familiar with.

As an example I'm learning ncurses these past couple days, and its significantly flow-breaking to have to switch focus away from the editor to either search on the web what a particular function takes as parameters, or open a separate terminal to read the man page for it. I'm still not familiar with the library so I frequently need to look up what a parameter represents in the context of the code, in addition to what type I should give it. Is there any way to do this while still using clangd as my lsp server?

Ive also included a screenshot of one such hover window for the ncurses function mvprintw.

 

Hello guys, Ive built a super simple web app to convert google maps urls to the osm format, mainly for my personal use but also for anyone who has this use case as well.

Most link formats work, but there are a couple that have been giving me particular trouble. Here are the formats that work as expected:

https://www.google.com/maps/place/Eiffel+Tower/@48.8584,2.2945,17z
https://google.com/maps/place/Statue+of+Liberty/@40.6892,-74.0445,17z
https://maps.app.goo.gl/SoDFgcPJKVPeZXqd8
https://www.google.co.uk/maps/place/Buckingham+Palace/@51.5014,-0.1419,17z
https://www.google.de/maps/place/Brandenburger+Tor/@52.5163,13.3777,17z

These 2 formats dont work on the server, but if I run the app locally they work and give a correct osm formatted link:

https://maps.app.goo.gl/jXqDkM2NWN55kZcd9?g_st=com.google.maps.preview.copy
https://maps.google.com/maps?q=Big+Ben%2C+London

You can test it on the actual website (gmaps2osm.de), but essentially if you try to convert links of this format on the actual website you get an Internal Server Error after around 10 seconds of it thinking.

Right now Im focusing on the .preview.copy formatted links. As you will see from the code below, I am using playwright to headlessly handle googles annoying redirects and consent forms:

from typing import final
from flask import Flask, request, render_template, jsonify
from datetime import datetime
import re
import urllib.parse
import requests
from playwright.sync_api import sync_playwright

# Test urls for regex:
# https://www.google.com/maps/place/Eiffel+Tower/@48.8584,2.2945,17z
# https://google.com/maps/place/Statue+of+Liberty/@40.6892,-74.0445,17z
# https://maps.google.com/maps?q=Big+Ben%2C+London # has an issue, doesnt work
# https://maps.app.goo.gl/4jnZLELvmpvBmFvx8
# https://maps.app.goo.gl/jXqDkM2NWN55kZcd9?g_st=com.google.maps.preview.copy
# https://www.google.co.uk/maps/place/Buckingham+Palace/@51.5014,-0.1419,17z
# https://www.google.de/maps/place/Brandenburger+Tor/@52.5163,13.3777,17z

debug_enabled = False
is_headless = not debug_enabled
print(f"is_headless: {is_headless}")
log_file_path = ""
app = Flask(__name__)

GMAPS_URL_RE = re.compile(
	r"""(?x)  # Verbose mode
	^https?://
	(
		(www\.)?
		(google\.[a-z.]+/maps)			  |		# www.google.com/maps, google.co.uk/maps, etc.
		(maps\.google\.[a-z.]+)			  |		# maps.google.com
		(goo\.gl/maps)					  |		# goo.gl/maps
		(maps\.app\.goo\.gl)					# maps.app.goo.gl
		# (maps\.app\.goo\.gl.*\.preview\.copy)	# maps.app.goo.gl(...).preview.copy
	)
	""",
	re.IGNORECASE
)

# ---- Dispatcher
def extract_coordinates(url: str):
	if ".preview.copy" in url:
		return handle_preview_copy_url(url)
	if "maps?q=" in url:
		return handle_browser_resolved_url(url)
	else:
		return handle_standard_url(url)

# ---- Handler: preview.copy links
def handle_preview_copy_url(url: str):
	url = url.split('?')[0]
	input_url = resolve_initial_redirect(url)
	if "consent.google.com" in input_url:
		parsed = urllib.parse.urlparse(input_url)
		query = urllib.parse.parse_qs(parsed.query)
		continue_url = query.get("continue", [""])[0]
		if continue_url:
			input_url = urllib.parse.unquote(continue_url)
		else:
			log_msg("ERROR", "No 'continue' parameter found.")
			return None, input_url
	final_url = extract_with_playwright(input_url)
	coord = extract_coords_from_url(final_url)
	return coord, final_url

# ---- Handler: links with only a query containing place names (https://maps.google.com/maps?q=Big+Ben%2C+London)
def handle_browser_resolved_url(url: str):
	input_url = resolve_initial_redirect(url)
	if "consent.google.com" in input_url:
		parsed = urllib.parse.urlparse(input_url)
		query = urllib.parse.parse_qs(parsed.query)
		continue_url = query.get("continue", [""])[0]
		if continue_url:
			input_url = urllib.parse.unquote(continue_url)
		else:
			log_msg("ERROR", "No 'continue' parameter found.")
			return None, input_url
	final_url = extract_with_playwright(input_url)
	coord = extract_coords_from_url(final_url)
	return coord, final_url

# ---- Handler: standard links
def handle_standard_url(url: str):
	try:
		# Follow redirect to get final destination
		response = requests.head(url, allow_redirects=True, timeout=10)
		final_url = response.url
		log_msg("DEBUG", "Final URL:", final_url)
	except requests.RequestException as e:
		raise RuntimeError(f"Failed to resolve standard URL: {e}")
	coords = extract_coords_from_url(final_url)
	return coords, final_url

# ---- Utility: redirect resolver
def resolve_initial_redirect(url: str):
	try:
		response = requests.get(url, allow_redirects=True, timeout=10)
		return response.url
	except Exception as e:
		log_msg("ERROR", "Redirect failed: ", e)
		return url

# ---- Utility: use playwright to get the final rendered URL
def extract_with_playwright(url:str):
	with sync_playwright() as p:
		browser = p.chromium.launch(headless=is_headless)
		page = browser.new_page()
		page.goto(url)
		# Click reject button if necessary
		try:
			page.locator('button:has-text("Reject all")').first.click(timeout=5000)
		except:
			pass # No reject button
		page.wait_for_function(
				"""() => window.location.href.includes('/@')""",
				timeout=15000
		)
		final_url = page.url
		log_msg("DEBUG", "Final URL: ", final_url)
		browser.close()
		return final_url

# ---- Utility: extract coordinates with regex patterns
def extract_coords_from_url(url: str):
	patterns = [
		r'/@([-.\d]+),([-.\d]+)',				 # Matches /@lat,lon
		r'/place/([-.\d]+),([-.\d]+)',			 # Matches /place/lat,lon
		r'/search/([-.\d]+),\+?([-.\d]+)',
		r'[?&]q=([-.\d]+),([-.\d]+)',			 # Matches ?q=lat,lon
		r'[?&]ll=([-.\d]+),([-.\d]+)',			 # Matches ?ll=lat,lon
		r'[?&]center=([-.\d]+),([-.\d]+)',		 # Matches ?center=lat,lon
		r'!3d([-.\d]+)!4d([-.\d]+)'				 # Matches !3dlat!4dlon
	]
	for pattern in patterns:
		match = re.search(pattern, url)
		if match:
			return match.groups()
	return None

# ---- Utility: logging function to output and write to file
def log_msg(level: str, msg: str, optional_arg = None):
	ts = datetime.now()
	iso_ts = ts.isoformat()
	if level == "DEBUG" and debug_enabled == False:
		return
	if optional_arg:
		log_line = f"[{iso_ts}]:[{level}]: {msg} {optional_arg}"
	else:
		log_line = f"[{iso_ts}]:[{level}]: {msg}"
	print(log_line)
	with open(log_file_path+"gmaps2osm_logs.txt", "a") as log_file:
		log_file.write(log_line+"\n")

@app.route("/", methods=["GET", "POST"])
def index():
	result = {}
	if request.method == "POST":
		url = request.form.get("gmaps_url", "").strip()
		log_msg("DEBUG", "URL:", url)
		if not url:
			result["error"] = "Please enter a Google Maps URL."
			log_msg("DEBUG", "Not a URL")
		else:
			try:
				if not GMAPS_URL_RE.search(url):
					result["error"] = "Please enter a valid Google Maps URL."
				else:
					coords, final_url = extract_coordinates(url)
					log_msg("DEBUG", "coords:", coords)
					if coords:
						lat, lon = coords
						result["latitude"] = lat
						result["longitude"] = lon
						result["osm_link"] = f"https://osmand.net/map?pin=%7Blat%7D%2C%7Blon%7D#16/{lat}/{lon}"
					else:
						raise ValueError("No coordinates found in the URL.")
			except ValueError as e:
				result["error"] = f"Error resolving or parsing URL: {e}"
	return render_template("index.html", **result)

if __name__ == "__main__":
	app.run(debug=True)

You can view all the code at the github: https://github.com/promitheas17j/gmaps2osm

But essentially its running as a docker container (my first project using docker woowoo) and this is the output of the logs on the server when I enter such a link:

$ docker logs -f gmaps2osm
[2025-08-15 17:42:00,132] ERROR in app: Exception on / [POST]
Traceback (most recent call last):
  File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 1511, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 919, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 917, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.10/dist-packages/flask/app.py", line 902, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)  # type: ignore[no-any-return]
  File "/app/app.py", line 164, in index
    coords, final_url = extract_coordinates(url)
  File "/app/app.py", line 42, in extract_coordinates
    return handle_preview_copy_url(url)
  File "/app/app.py", line 61, in handle_preview_copy_url
    final_url = extract_with_playwright(input_url)
  File "/app/app.py", line 113, in extract_with_playwright
    page.wait_for_url("**/@**", timeout=15000)
  File "/usr/local/lib/python3.10/dist-packages/playwright/sync_api/_generated.py", line 9162, in wait_for_url
    self._sync(
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_sync_base.py", line 115, in _sync
    return task.result()
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_page.py", line 584, in wait_for_url
    return await self._main_frame.wait_for_url(**locals_to_params(locals()))
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_frame.py", line 263, in wait_for_url
    async with self.expect_navigation(
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_event_context_manager.py", line 33, in __aexit__
    await self._future
  File "/usr/local/lib/python3.10/dist-packages/playwright/_impl/_frame.py", line 239, in continuation
    event = await waiter.result()
playwright._impl._errors.TimeoutError: Timeout 15000ms exceeded.
=========================== logs ===========================
waiting for navigation to "**/@**" until 'load'
============================================================

This was when I gave this URL as input: https://maps.app.goo.gl/jXqDkM2NWN55kZcd9?g_st=com.google.maps.preview.copy

Anyone have any idea why playwright is throwing errors at me?

Thanks in advance, I really appreciate any help you can give me. Ive been banging my head about this issue on and off the past couple of months.

 

Hello everyone!

As the title says, I am trying to set up email alerts on my server whenever there is a successful ssh connection (will also setup the same for failed connections with fail2ban later). I already have the email script created and it works (I use it to monitor the directories containing all of these security scripts for changes so that I also get notified if anything critical is modified or deleted in those directories).

I also created a very basic user called test for - you guessed it - testing purposes. This user doesn't have a home directory or anything like that.

Here are the relevant scripts:

$ cat /usr/local/bin/login-alert.sh
#!/bin/bash

# Sends alerts only for real terminals not cron jobs
if [[ -n "$SSH_CONNECTION" ]]; then
	USERNAME=$(whoami)
	IP=$(echo $SSH_CONNECTION | awk '{print $1}')
	HOST=$(hostname)
	DATETIME=$(date)
	/usr/local/bin/semail \
		-s "[CRITICAL] SSH Login to $HOST" \
	 	-b "Login detected:\n\nUser: $USERNAME\nIP: $IP\nTime: $DATETIME\nTTY: $SSH_TTY"
fi

$ cat /usr/local/bin/semail
#!/bin/bash

# Default values
TO="my_email@here.com"
FROM="notifications@my_server.com"
SUBJECT=""
BODY=""
BODY_FILE=""


# Help function
show_help() {
cat <<EOF
Usage: $0 [OPTIONS]

Send a test email using Postfix.

Options:
  -t, --to EMAIL            Recipient email address (default: $TO)
  -s, --subject TEXT        Subject of the email (required)
  -b, --body TEXT           Body text of the email
  -f, --body-file FILE      File to read body text from (overrides --body)
  -h, --help                Show this help message

If no body or body-file is provided, you will be prompted to enter the body interactively.

Examples:
  $0 -s "Test subject" -b "Hello\nThis is a test"
  $0 --subject "Test" --body-file message.txt
EOF
}

# Parse arguments
while [[ "$#" -gt 0 ]]; do
	case "$1" in
		-t|--to)
			TO="$2"
			shift 2
			;;
		-s|--subject)
			SUBJECT="$2"
			shift 2
			;;
		-b|--body)
			BODY="$2"
			shift 2
			;;
		-f|--body-file)
			BODY_FILE="$2"
			shift 2
			;;
		-h|--help)
			show_help
			exit 0
			;;
		*)
			echo "Unknown option: $1"
			show_help
			exit 1
			;;
	esac
done

# Validate required parameters
if [[ -z "$SUBJECT" ]]; then
	echo "Error: --subject is required."
	show_help
	exit 1
fi

# Handle body input
if [[ -n "$BODY_FILE" ]]; then
	if [[ ! -f "$BODY_FILE" ]]; then
		echo "Error: Body file '$BODY_FILE' does not exist."
		exit 1
	fi
	BODY=$(<"$BODY_FILE")
elif [[ -z "$BODY" ]]; then
	echo "Enter the body of the email (end with Ctrl-D):"
	BODY=$(</dev/stdin)
fi

# Send email
{
	echo "From: $FROM"
	echo "To: $TO"
	echo "Subject: $SUBJECT"
	echo "Content-Type: text/plain; charset=UTF-8"
	echo
	printf "%b\n" "$BODY"
} | /usr/sbin/sendmail -t -f "$FROM"

# /usr/sbin/sendmail -f "$FROM" "$TO" <<EOF
# From: $FROM
# To: $TO
# Subject: $SUBJECT

# $BODY
# EOF

echo "Email sent to $TO"

And here is the output I see when I login as the test user:

ssh test@my_server.com
test@my_server.com's password:
dir=/ failed: exit code 2
dir=/ failed: exit code 2
Linux my_server 6.1.0-37-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.140-1 (2025-05-22) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Aug 15 07:08:24 2025 from my_ip_address
Could not chdir to home directory /home/test: No such file or directory

I don't get email alerts for any user, neither the test user nor my regular admin user.

Here is my /etc/pam.d/sshd relevant lines:

# Standard Un*x session setup and teardown.
account optional pam_exec.so seteuid dir=/ /usr/local/bin/login_notify.sh
@include common-session

I also tried with session instead of account and without the dir=/ part.

Can anyone help me troubleshoot this please?

Thanks in advance. Of course if you need any more info I'll do my best to provide it :)

 

Hello everyone (whoever is subbed to this community)! Ive been wanting to get into inline skating for a while now, but just dont have the knowledge of where to start.

Im in Europe, specifically Cyprus (so first-hand buying options are limited) so if I would bite the bullet and order skates online to learn it would be without trying them on first. I do plan on moving to the Netherlands where I know theres an awesome skating shop in Amsterdam, but that could be at any time this month or year (depends on when I find a job).

Up to now I bought some ultra cheap skates on black friday a couple years ago (No Fears I believe they were), which after the second day of practicing in the park had the frame get loose (and it wasnt designed to be able to tighten or fix). That was super disappointing because I was really excited to get into this hobby.

Anyways, what are your thoughts? Should I see what options I have for getting into it while I am still here, or wait until I get to a more "civilised" part of the world where there are actually opportunities to do stuff? xD

Also, if you recommend I get into it right away, how should I pick as good a skate as possible without actually trying it on first?

Thanks in advance!

 

Hello guys. I have island installed and have my "work profile" installed, which contains among others my browser in the island tab. The situation is that I have several PWAs that I dont want to receive notifications for while I am at work as they are distracting and unnecessarily annoying, but I want to receive them normally while not at work.

I have been trying to figure out how to get it set up so that I can both trigger the actions at scheduled times, or manually through the quick tile I created from macrodroid (my work hours are not really stable/fixed).

However, when testing with a push notification testing site, regardless what I do I still get the notifications.

Here is my setup so far:

Macros:
Enable Work Profile
--------------------------
Triggers:
    Day/Time: 08:00 Mon, Fri
    Quick Tile On/Press

Actions:
    Action 1:
        Target: Broadcast
        Send Intent: island.intent.action.FREEZE_APP
        Extra 1: package_name = com.brave.browser
    Action 2:
        Display Notification (with a message saying work mode enabled)

Constraints: None

Disable Work Profile
--------------------------
Triggers:
    Quick Tile Off

Actions:
    Action 1:
        Target: Broadcast
        Send Intent: island.intent.action.UNFREEZE_APP
        Extra 1: package_name = com.brave.browser
    Action 2:
        Display Notification (with a message saying work mode disabled)

Constraints:
    Day of the Week: Mon
    Time of Day: 19:00 - 19:01
------------------- OR --------------------------
    Day of the Week: Fri
    Time of Day: 22:00 - 22:01

Some things to note:

I am using /e/os version 3.0.1-t-20250606498724-official-FP5 Android is version 13

What am I doing wrong here? Ideally I would like to have as few apps installed as possible to achieve a single task, but as I understand it macrodroid doesnt have the necessary permissions to affect other apps notifications (hence why island is necessary).

If there is another way which is easier to achieve what I am trying to do I'm all ears, however I do not want to use do not disturb for this purpose because obviously I need to be able to use my phone normally while at work except for those 2-3 apps I dont want to receive notifications for, but there are also situations where I want a full DND experience where I will get nothing coming through, not even alarms (e.g. meetings/classes, etc). Also for those unfamiliar with /e/os, it doesn't currently have the Focus Mode feature so that is also out of the picture.

Many thanks in advance!

25
submitted 6 months ago* (last edited 6 months ago) by promitheas@programming.dev to c/buyeuropean@feddit.uk
 

Hello everyone! I just wrote an extremely simply single-page tool using just HTML and Flask to convert google maps links to Osmand.net links, and I would like to host it somewhere.

I don't need any fancy bells and whistles, as long as it supports Flask as a backend.

Im no web developer, so I haven't actually hosted my own page anywhere before. As such, simplicity of use and setup is quite important. For example if it allows me to also buy the domain in the same platform thats good.

While I use Flask, there is no data being stored. All the flask app does is take the link given by the user, convert it to the osmand.net format, and return it. Super simple!

I looked on buy-european.net and found Infomaniak Web Hosting. I quite like the fact that they use 100% renewable energy to power their servers according to the page above, but I'm not sure if it would be the best option given how inexperienced with all this I am.

Would love to hear your suggestions! Thanks

Edit: Ended up going with hetzner. Site is pretty much set up right now.

gmaps2osm.de

It has some screen-reader support (still need to get it tested by visually impaired people), and is also set up so that you can install it as a PWA on your mobile device (add to home screen).

Here is the github repo: https://github.com/promitheas17j/gmaps2osm

I would really appreciate any feedback from experienced and not so experienced web developers alike :D

view more: next ›