diff --git a/ansible/roles/common/files/bluesky.conf b/ansible/roles/common/files/bluesky.conf new file mode 100644 index 00000000..810e623c --- /dev/null +++ b/ansible/roles/common/files/bluesky.conf @@ -0,0 +1,2 @@ +bluesky_username_and_server_instance_url="" +bluesky_app_password="" \ No newline at end of file diff --git a/ansible/roles/common/files/rn2_upgrade.sh b/ansible/roles/common/files/rn2_upgrade.sh index 61ca43e2..ece34ec2 100644 --- a/ansible/roles/common/files/rn2_upgrade.sh +++ b/ansible/roles/common/files/rn2_upgrade.sh @@ -95,6 +95,25 @@ if [[ $? != 0 ]]; then exit 1 fi +echo "###################################################################" +echo "# Check existing settings.yml meets requirements for new repository" +echo "###################################################################" + +python3 /tmp/raspberry-noaa-v2/scripts/tools/validate_yaml.py ${HOME}/raspberry-noaa-v2/config/settings.yml /tmp/raspberry-noaa-v2/config/settings_schema.json +v_result=$? + +if [[ ${v_result} -ne 0 ]]; then + cp -p /tmp/raspberry-noaa-v2/config/settings.yml /tmp/settings.yml + echo "" + echo "Your existing ${HOME}/raspberry-noaa-v2/config/settings.yml is missing one or more new parameters, which are required by the repository you are trying to upgraded to." + echo "" + echo "Please see the above \"required property\"'s reported and add to your settings.yml before trying to upgrade again." + echo "" + echo "Please look at /tmp/settings.yml for example of the missing parameter" + \rm -rf /tmp/raspberry-noaa-v2 + exit 1 +fi + echo "#####################################################" echo "# Perform RN2 Key file backup/stage" echo "#####################################################" diff --git a/ansible/roles/common/tasks/sdr.yml b/ansible/roles/common/tasks/sdr.yml index 15a053ec..48d136b3 100644 --- a/ansible/roles/common/tasks/sdr.yml +++ b/ansible/roles/common/tasks/sdr.yml @@ -23,6 +23,54 @@ src: blacklist-msi.conf dest: /etc/modprobe.d/blacklist-msi.conf +# Due to the RTL drivers presently available to Debian 12 not supporting +# RTL-SDR V4 receivers properly, we must ensure they are deleted prior to +# OSMOCOM drivers being installed. +# +# The original librtlsdr package will remain installed, but the removal of the library +# will allow satdump to use the correct OSMOCOM driver for capturing telemtry +# +# Note - LMDE Bookworm 64-bit does not have this problem +# +# librtlsdr-dev/stable 0.6.0-4 arm64 +# librtlsdr-dev/stable 0.6.0-4 armhf +# librtlsdr0/stable 0.6.0-4 arm64 +# librtlsdr0/stable 0.6.0-4 armhf + +- name: Find librtlsdr* files to remove from Bookworm (RTL-SDR V4 resolution) + find: + paths: /usr/lib/aarch64-linux-gnu/ + patterns: "librtlsdr.so*" + use_regex: true + file_type: file + register: libraries_to_delete + when: raspbian_version.stdout == 'bookworm' and system_architecture == 'arm64' + +- name: Remove librtlsdr.so* from Bookworm (RTL-SDR V4 resolution) + become: yes + file: + path: "{{ item.path }}" + state: absent + with_items: "{{ libraries_to_delete.files }}" + when: raspbian_version.stdout == 'bookworm' and system_architecture == 'arm64' + +- name: Find librtlsdr* files to remove from Bookworm (RTL-SDR V4 resolution) + find: + paths: /lib/arm-linux-gnueabihf/ + patterns: "librtlsdr.so*" + use_regex: true + file_type: file + register: libraries_to_delete + when: raspbian_version.stdout == 'bookworm' and system_architecture == 'armhf' + +- name: Remove librtlsdr.so* from Bookworm (RTL-SDR V4 resolution) + become: yes + file: + path: "{{ item.path }}" + state: absent + with_items: "{{ libraries_to_delete.files }}" + when: raspbian_version.stdout == 'bookworm' and system_architecture == 'armhf' + - name: check if RTL-SDR software is installed stat: path: /usr/local/bin/rtl_sdr diff --git a/ansible/roles/common/tasks/social_media.yml b/ansible/roles/common/tasks/social_media.yml index 557f3094..8df98e96 100644 --- a/ansible/roles/common/tasks/social_media.yml +++ b/ansible/roles/common/tasks/social_media.yml @@ -92,7 +92,7 @@ - facebook-sdk state: present executable: pip3 - when: enable_twitter_push | bool and raspbian_version.stdout == 'bullseye' + when: enable_facebook_push | bool and raspbian_version.stdout == 'bullseye' - name: drop template Facebook config file copy: @@ -118,7 +118,7 @@ - facebook-sdk state: present executable: pip3 - when: enable_twitter_push | bool and raspbian_version.stdout == 'bullseye' + when: enable_instagram_push | bool and raspbian_version.stdout == 'bullseye' - name: drop template Instagram config file copy: @@ -144,7 +144,7 @@ - Mastodon.py state: present executable: pip3 - when: enable_twitter_push | bool and raspbian_version.stdout == 'bullseye' + when: enable_mastodon_push | bool and raspbian_version.stdout == 'bullseye' - name: drop template Mastodon config file copy: @@ -157,4 +157,30 @@ when: enable_mastodon_push | bool ######################################################################################################## -... + +#Bluesky + +- name: install atproto if Bluesky push is enabled (bookworm) + command: pip3 install atproto --break-system-packages + when: enable_bluesky_push | bool and raspbian_version.stdout == 'bookworm' + +- name: install atproto if Mastodon push is enabled (bullseye) + pip: + name: + - atproto + state: present + executable: pip3 + when: enable_bluesky_push | bool and raspbian_version.stdout == 'bullseye' + +- name: drop template Bluesky config file + copy: + src: bluesky.conf + dest: /home/{{ target_user }}/.bluesky.conf + force: no + owner: "{{ target_user }}" + group: "{{ target_user }}" + mode: 0600 + when: enable_bluesky_push | bool + +######################################################################################################## +... \ No newline at end of file diff --git a/ansible/roles/common/templates/noaa-v2.conf.j2 b/ansible/roles/common/templates/noaa-v2.conf.j2 index 54a07acd..d1efe6c1 100644 --- a/ansible/roles/common/templates/noaa-v2.conf.j2 +++ b/ansible/roles/common/templates/noaa-v2.conf.j2 @@ -143,6 +143,7 @@ ENABLE_DISCORD_PUSH={{ enable_discord_push|lower }} DISCORD_NOAA_WEBHOOK='{{ discord_noaa_webhook_url }}' DISCORD_METEOR_WEBHOOK='{{ discord_meteor_webhook_url }}' ENABLE_TWITTER_PUSH={{ enable_twitter_push|lower }} +ENABLE_BLUESKY_PUSH={{ enable_bluesky_push|lower }} ENABLE_MASTODON_PUSH={{ enable_mastodon_push|lower }} ENABLE_FACEBOOK_PUSH={{ enable_facebook_push|lower }} ENABLE_INSTAGRAM_PUSH={{ enable_instagram_push|lower }} @@ -173,4 +174,3 @@ WEBPANEL_TLS_PORT={{ web_tls_port }} WEB_SERVER_NAME={{ web_server_name }} ENABLE_TLS={{ enable_tls|lower }} ENABLE_NON_TLS={{ enable_non_tls|lower }} - diff --git a/ansible/roles/common/templates/satdump_cfg.json.j2 b/ansible/roles/common/templates/satdump_cfg.json.j2 index 49ad1926..b8872322 100644 --- a/ansible/roles/common/templates/satdump_cfg.json.j2 +++ b/ansible/roles/common/templates/satdump_cfg.json.j2 @@ -346,7 +346,7 @@ // 49008, // FengYun-3E // 57490, // FengYun-3F // 56232, // FengYun-3G - 35865, // METEOR-M1 + 35865 // METEOR-M1 // 40069, // METEOR-M2 // 44387, // METEOR-M2-2 // 57166, // METEOR-M2-3 @@ -401,7 +401,7 @@ // 46984, // Sentinel-6 // 48900, // TUBIN // 57172, // UmKA-1 (RS40S) - 56211 // Inspire-Sat 7 + // 56211 // Inspire-Sat 7 // 40376, // SMAP // 44874, // CHEOPS // 36036, // SMOS diff --git a/config/settings.yml b/config/settings.yml index 04c00427..cc1722f5 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -312,6 +312,7 @@ pushover_apitoken: '' pushover_user: '' pushover_prio: 0 enable_twitter_push: false +enable_bluesky_push: false enable_mastodon_push: false enable_facebook_push: false enable_instagram_push: false @@ -320,4 +321,4 @@ slack_push_url: '' slack_push_to: '' slack_link: 'https://XXXX/captures/listImages' enable_matrix_push: false -... +... \ No newline at end of file diff --git a/config/settings_schema.json b/config/settings_schema.json index 4e0fc886..0d124738 100644 --- a/config/settings_schema.json +++ b/config/settings_schema.json @@ -209,6 +209,7 @@ "discord_meteor_webhook_url": { "type": "string" }, "enable_twitter_push": { "type": "boolean" }, "enable_mastodon_push": { "type": "boolean" }, + "enable_bluesky_push": { "type": "boolean" }, "enable_facebook_push": { "type": "boolean" }, "enable_instagram_push": { "type": "boolean" }, "enable_slack_push": { "type": "boolean" }, @@ -337,6 +338,7 @@ "discord_meteor_webhook_url", "enable_twitter_push", "enable_mastodon_push", + "enable_bluesky_push", "enable_facebook_push", "enable_instagram_push", "enable_matrix_push", diff --git a/scripts/push_processors/push_bluesky.py b/scripts/push_processors/push_bluesky.py new file mode 100644 index 00000000..5a90b772 --- /dev/null +++ b/scripts/push_processors/push_bluesky.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 + +import os +import sys +from atproto import Client + +def parse_bluesky_config(file_path): + with open(file_path, 'r') as file: + lines = file.readlines() + + # Initialize variable to store the access token + bluesky_username_and_server_instance_url = None + bluesky_app_password = None + + # Process each line in the file + for line in lines: + # Remove leading and trailing whitespaces from the line + line = line.strip() + + # Skip empty lines or lines starting with a '#' (comments) + if not line or line.startswith('#'): + continue + + # Split the line into key and value using the '=' separator + key, value = line.split('=', 1) + + # Remove leading and trailing whitespaces from the key and value + key = key.strip() + value = value.strip() + + # Check if the key is 'bluesky_username_and_server_instance_url' or 'bluesky_app_password' + if key == 'bluesky_username_and_server_instance_url': + bluesky_username_and_server_instance_url = value.strip('\'"') + elif key == 'bluesky_app_password': + bluesky_app_password = value.strip('\'"') + + return bluesky_username_and_server_instance_url, bluesky_app_password + +config_path = os.path.expanduser("~/.bluesky.conf") + +bluesky_username_and_server_instance_url, BLUESKY_APP_PASSWORD = parse_bluesky_config(config_path) + +annotation = sys.argv[1] +images = [] +for file in sys.argv[2:]: + images.append(file) + +# split images into groups (Bluesky allows maximum 4 per post) +if len(images) > 4: + images = [ images[i:i+4] for i in range(0, len(images), 4) ] +else: + images = [ images ] + +client = Client() +client.login(bluesky_username_and_server_instance_url, BLUESKY_APP_PASSWORD) + +post_text = annotation + '\n\n#NOAA #NOAA15 #NOAA18 #NOAA19 #MeteorM2_3 #MeteorM2_4 #weather #weathersats #APT #LRPT #wxtoimg #MeteorDemod #rtlsdr #gpredict #raspberrypi #RN2 #ISS' + +image_data = [] +for image_path in images: + for i in range(0, 3): + with open(image_path[i], 'rb') as f: + image_data.append(f.read()) + client.send_images(text=post_text, images=image_data) \ No newline at end of file diff --git a/scripts/receive_meteor.sh b/scripts/receive_meteor.sh index 9d03d23d..e45d3570 100644 --- a/scripts/receive_meteor.sh +++ b/scripts/receive_meteor.sh @@ -453,6 +453,12 @@ if [ -n "$(find /srv/images -maxdepth 1 -type f -name "$(basename "$IMAGE_FILE_B python3 $PUSH_PROC_DIR}/push_mastodon.py "${push_annotation}" ${push_file_list} >> $NOAA_LOG 2>&1 fi + # handle Bluesky pushing if enabled + if [ "${ENABLE_BLUESKY_PUSH}" == "true" ]; then + log "Pushing image enhancements to Bluesky" "INFO" + python3 ${PUSH_PROC_DIR}/push_bluesky.py "${push_annotation}" ${push_file_list} >> $NOAA_LOG 2>&1 + fi + # handle Instagram pushing if enabled if [ "${ENABLE_INSTAGRAM_PUSH}" == "true" ]; then log "Pushing image enhancements to Instagram" "INFO" @@ -492,4 +498,4 @@ fi TIMER_END=$(date '+%s') DIFF=$(($TIMER_END - $TIMER_START)) PROC_TIME=$(date -ud "@$DIFF" +'%H:%M.%S') -log "Total processing time: ${PROC_TIME}" "INFO" +log "Total processing time: ${PROC_TIME}" "INFO" \ No newline at end of file diff --git a/scripts/receive_noaa.sh b/scripts/receive_noaa.sh index d75b017a..6ebb72be 100755 --- a/scripts/receive_noaa.sh +++ b/scripts/receive_noaa.sh @@ -456,21 +456,31 @@ if [ -n "$(find /srv/images -maxdepth 1 -type f -name "$(basename "$IMAGE_FILE_B pass_id=$($SQLITE3 $DB_FILE "SELECT id FROM decoded_passes ORDER BY id DESC LIMIT 1;") ${PUSH_PROC_DIR}/push_slack.sh "${push_annotation} <${SLACK_LINK}?pass_id=${pass_id}>\n" $push_file_list >> $NOAA_LOG 2>&1 fi + # handle Twitter pushing if enabled if [ "${ENABLE_TWITTER_PUSH}" == "true" ]; then log "Pushing image enhancements to Twitter" "INFO" ${PUSH_PROC_DIR}/push_twitter.sh "${push_annotation}" $push_file_list >> $NOAA_LOG 2>&1 fi + + # handle Bluesky pushing if enabled + if [ "${ENABLE_BLUESKY_PUSH}" == "true" ]; then + log "Pushing image enhancements to Bluesky" "INFO" + python3 ${PUSH_PROC_DIR}/push_bluesky.py "${push_annotation}" ${push_file_list} >> $NOAA_LOG 2>&1 + fi + # handle Mastodon pushing if enabled if [ "${ENABLE_MASTODON_PUSH}" == "true" ]; then log "Pushing image enhancements to Mastodon" "INFO" python3 ${PUSH_PROC_DIR}/push_mastodon.py "${push_annotation}" ${push_file_list} >> $NOAA_LOG 2>&1 fi + # handle Facebook pushing if enabled if [ "${ENABLE_FACEBOOK_PUSH}" == "true" ]; then log "Pushing image enhancements to Facebook" "INFO" python3 ${PUSH_PROC_DIR}/push_facebook.py "${push_annotation}" "${push_file_list}" >> $NOAA_LOG 2>&1 fi + # handle Instagram pushing if enabled if [ "${ENABLE_INSTAGRAM_PUSH}" == "true" ]; then if [[ "$daylight" -eq 1 ]]; then @@ -482,11 +492,13 @@ if [ -n "$(find /srv/images -maxdepth 1 -type f -name "$(basename "$IMAGE_FILE_B python3 ${PUSH_PROC_DIR}/push_instagram.py "${push_annotation}" $(sed 's|/srv/images/||' <<< "${IMAGE_FILE_BASE}-instagram.jpg") ${WEB_SERVER_NAME} >> $NOAA_LOG 2>&1 rm "${IMAGE_FILE_BASE}-instagram.jpg" fi + # handle Matrix pushing if enabled if [ "${ENABLE_MATRIX_PUSH}" == "true" ]; then log "Pushing image enhancements to Matrix" "INFO" ${PUSH_PROC_DIR}/push_matrix.sh "${push_annotation}" $push_file_list >> $NOAA_LOG 2>&1 fi + if [ "${ENABLE_EMAIL_PUSH}" == "true" ]; then IFS=' ' read -ra image_file_array <<< "$push_file_list" for i in "${image_file_array[@]}"; do @@ -494,6 +506,7 @@ if [ -n "$(find /srv/images -maxdepth 1 -type f -name "$(basename "$IMAGE_FILE_B ${PUSH_PROC_DIR}/push_email.sh "${EMAIL_PUSH_ADDRESS}" "$i" "${push_annotation}" >> $NOAA_LOG 2>&1 done fi + if [ "${ENABLE_DISCORD_PUSH}" == "true" ]; then IFS=' ' read -ra image_file_array <<< "$push_file_list" for i in "${image_file_array[@]}"; do @@ -510,4 +523,4 @@ fi TIMER_END=$(date '+%s') DIFF=$(($TIMER_END - $TIMER_START)) PROC_TIME=$(date -ud "@$DIFF" +'%H:%M.%S') -log "Total processing time: ${PROC_TIME}" "INFO" +log "Total processing time: ${PROC_TIME}" "INFO" \ No newline at end of file