Just to give everyone here an update, signal reports have been added to our AutoQSL/Contact View!
where do I find the AutoQSL/Contact View feature
You can click the eye icon next to any of your contacts to get to the Contact View, which is based on an auto-generated QSL card for each contact!
More comments per @AC1TP !
We should have a picture section in logs. For Qso cards, as well as a separate qso card book. That way we can confirm contacts for starters with non WRL members. But also for historical context. Secondly we could track stats under a qso card page and have leaderboards awards etc. Coolest cards of last 24 hours , 7 days, month etc. I belive this will be a great feature that generates massive intrest a qso card scrapbook with live real-time Stat tracking. It will generate intrest for certain contacts. Plus highlight individual creativity on a proper level of intrest. I also belive it will generate positive engagement in the Art of Radio while importing a massive amount of new users. We should be trying to encompass all things of The Art of Radio into one platform. I see this as a place where there is no limit to the potential for greatness. A homebrew section is also another great area that will drive usage and engagement. This would entail schematics and all things home brewed. We could also hold contests for limited run production qrp gear to help fund the operation. The reward being a wall plaque and one of the first off the production line of your winning design. Of course these would be limited production runs say 12 months or x amount of units. Making them rare treasures that hold an inherent value. Again it gives a chance for highlighting active engagement and generation of more users. Also a review/journalism section for legitimate equipment reviews. Wether it be antenna or transceiver. Store-bought or homebrew. Well in the intrest of not being long-winded wink wink lol. I will leave it at that of course with an air of enthusiasm and excitement to see the dawn of something great on the horizon of a craft in need of a proper infusion of love.
A post was split to a new topic: Add Address for Sending QSL Cards to Single Contact View
I would love to see something like this put to use for WRL members. As a new member, I can quickly exchange with members that I contact on the air.
72/73 de Warren, WQ1C
Below is an example of a complete Python program that may meet the requirements:
- Template Selection: The user can either choose a default QSL card template or provide a custom image file. In the custom case, the program prompts the user for the coordinates where each piece of form data should be placed.
- Form Data: The user is prompted to input details (such as callsign, date, frequency, location, etc.) that are then overlaid on the chosen template.
- Image Generation: Using the Python Imaging Library (PIL/Pillow), the program opens the template image and draws the provided text at the designated coordinates. The output is saved as a new image (e.g.,
generated_qsl.jpg
). - Email Sending: The program can email the generated QSL card image as an attachment using Pythonâs built-in SMTP libraries. (In this sample, Gmailâs SMTP server is used with SSL.)
Below is the full code with inline comments explaining each section. You can modify the fields or add more according to your needs:
#!/usr/bin/env python3
import os
from PIL import Image, ImageDraw, ImageFont
import smtplib
from email.message import EmailMessage
def generate_qsl_card(template_path, output_path, form_data, coordinates, font_path="arial.ttf", font_size=24):
"""
Generates a QSL card by overlaying text onto a template image.
Parameters:
- template_path: path of the image template.
- output_path: where to save the generated QSL card.
- form_data: dictionary of field names and user-provided data.
- coordinates: dictionary of field names and (x, y) coordinates.
- font_path: path to the TrueType font file to use.
- font_size: size of the text.
Returns:
- The output file path of the generated image.
"""
try:
base = Image.open(template_path).convert("RGB")
except Exception as e:
print(f"Error opening template image: {e}")
return None
draw = ImageDraw.Draw(base)
try:
font = ImageFont.truetype(font_path, font_size)
except Exception as e:
print(f"Error loading font '{font_path}': {e}")
print("Falling back to default font.")
font = ImageFont.load_default()
for field, text in form_data.items():
if field in coordinates:
pos = coordinates[field]
draw.text(pos, text, font=font, fill="black")
else:
print(f"Warning: No coordinates provided for field '{field}'.")
base.save(output_path)
return output_path
def send_email(sender_email, sender_password, recipient_email, subject, body, attachment_path):
"""
Sends an email with an attachment using Gmail's SMTP server.
Parameters:
- sender_email: your email address.
- sender_password: your email password (or app-specific password).
- recipient_email: the email address of the recipient.
- subject: subject line of the email.
- body: body text of the email.
- attachment_path: path to the file that will be attached.
"""
msg = EmailMessage()
msg['Subject'] = subject
msg['From'] = sender_email
msg['To'] = recipient_email
msg.set_content(body)
try:
with open(attachment_path, 'rb') as f:
file_data = f.read()
file_name = os.path.basename(attachment_path)
# Assuming the image is a JPEG; adjust type if needed
msg.add_attachment(file_data, maintype="image", subtype="jpeg", filename=file_name)
except Exception as e:
print(f"Error reading attachment file: {e}")
return False
try:
# Using Gmail's SMTP server with SSL; change these if you use another email provider
with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
smtp.login(sender_email, sender_password)
smtp.send_message(msg)
print("Email sent successfully!")
return True
except Exception as e:
print(f"Error sending email: {e}")
return False
def main():
print("Welcome to the QSL Card Generator!")
# Template Selection
choice = input("Enter 'default' to use the default template or 'custom' to use your own: ").strip().lower()
if choice == 'default':
# Ensure that default_template.jpg exists in the working directory.
template_path = "default_template.jpg"
# Coordinates for default template fields (adjust these as per your template design)
coordinates = {
"callsign": (100, 150),
"date": (100, 200),
"frequency": (100, 250),
"location": (100, 300)
}
elif choice == 'custom':
template_path = input("Enter the full path to your custom template image: ").strip()
coordinates = {}
print("Enter coordinates (x y) for each field. For example, type '100 150' for callsign position.")
for field in ["callsign", "date", "frequency", "location"]:
coords = input(f"Enter x and y coordinates for '{field}': ").strip().split()
if len(coords) != 2:
print("Invalid coordinates provided. Exiting.")
return
try:
coordinates[field] = (int(coords[0]), int(coords[1]))
except ValueError:
print("Coordinates must be integers. Exiting.")
return
else:
print("Invalid choice. Exiting.")
return
# Gather Form Data
form_data = {}
form_data["callsign"] = input("Enter your callsign: ").strip()
form_data["date"] = input("Enter the contact date (YYYY-MM-DD): ").strip()
form_data["frequency"] = input("Enter the frequency (MHz): ").strip()
form_data["location"] = input("Enter your location: ").strip()
output_path = "generated_qsl.jpg"
font_path = "arial.ttf" # Make sure the font file exists or use an alternative TTF font file.
font_size = 24
print("Generating your QSL card...")
generated_card = generate_qsl_card(template_path, output_path, form_data, coordinates, font_path, font_size)
if generated_card:
print(f"QSL card generated successfully at '{generated_card}'.")
else:
print("Failed to generate QSL card.")
return
# Email Option
email_choice = input("Would you like to email the QSL card? (y/n): ").strip().lower()
if email_choice == 'y':
sender_email = input("Enter your email address (sender): ").strip()
sender_password = input("Enter your email password (or app-specific password): ").strip()
recipient_email = input("Enter recipient email address: ").strip()
subject = "Your Electronic QSL Card"
body = "Attached is the QSL card you generated using our service."
send_email(sender_email, sender_password, recipient_email, subject, body, generated_card)
else:
print("Email skipped. Your QSL card is ready.")
if __name__ == "__main__":
main()
Explanation
-
Template and Customization:
- When the program runs, it first asks if you want to use a default template or provide your own.
- In the default case, the program expects a file called
default_template.jpg
in the current directory and uses preset coordinates to position the text. - For a custom template, you provide your image fileâs path, and the program prompts you to enter the coordinates for each field (callsign, date, frequency, location). This makes it flexible enough for any custom design.
-
Form Data Collection:
- The program collects user input for various fields (for example, callsign and contact details) that are to be inserted on the card.
-
Image Generation with PIL:
- The
generate_qsl_card
function opens the template image, usesImageDraw
to overlay text input at the designated coordinates, and saves the resulting image.
- The
-
Email Sending:
- If you choose to email your electronic QSL card, the program uses Pythonâs
smtplib
andEmailMessage
to send the generated image as an attachment. In this example, Gmailâs SMTP server is used (remember that you might need to generate an app-specific password depending on your security settings).
- If you choose to email your electronic QSL card, the program uses Pythonâs
-
Modifications and Next Steps:
- You can enhance this sample program by adding error handling, a graphic user interface (using frameworks like Tkinter or Flask), and even support for multiple QSL card templates.
- You may also incorporate configuration files (using JSON or YAML) to save template setups and coordinate mappings for reuse.
This example is a starting point that meets the outlined requirements. Thereâs plenty of room to extend the functionalityâfor instance, adding a preview feature for the QSL card or supporting other file formats for the template image. Enjoy coding and feel free to ask if youâd like to explore further enhancements or modifications!
I just clicked download image and something seemed to happen but I canât find the image. It didnât go into my download folder. Where do the images go and is there a way to change the location - thanks!