diff --git a/README.md b/README.md index ac6f367c2..0904194c4 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # NewsBlur - * NewsBlur is a personal news reader bringing people together - to talk about the world. A new sound of an old instrument. - * [www.newsblur.com](http://www.newsblur.com). - * Created by [Samuel Clay](http://www.samuelclay.com). - * Twitter: [@samuelclay](http://twitter.com/samuelclay) and - [@newsblur](http://twitter.com/newsblur). +- NewsBlur is a personal news reader bringing people together + to talk about the world. A new sound of an old instrument. +- [www.newsblur.com](https://www.newsblur.com). +- Created by [Samuel Clay](https://www.samuelclay.com). +- X/Twitter: [@samuelclay](https://x.com/samuelclay) and + [@newsblur](https://x.com/newsblur). Get it on F-Droid @@ -16,46 +16,47 @@ ## Features - 1. Shows the original site (you have to see it to believe it). - 2. Hides stories you don't want to read based on tags, keywords, authors, etc. - 3. Highlights stories you want to read, based on the same criteria. +1. Shows the original site (you have to see it to believe it). +2. Hides stories you don't want to read based on tags, keywords, authors, etc. +3. Highlights stories you want to read, based on the same criteria. ## Technologies ### Server-side - * [Python 3.7+](http://www.python.org): The language of choice. - * [Django](http://www.djangoproject.com): Web framework written in Python, used - to serve all pages. - * [Celery](http://ask.github.com/celery) & [RabbitMQ](http://www.rabbitmq.com): - Asynchronous queueing server, used to fetch and parse RSS feeds. - * [MongoDB](http://www.mongodb.com), [Pymongo](https://pypi.python.org/pypi/pymongo), & - [Mongoengine](http://www.github.com/hmarr/mongoengine): Non-relational database, - used to store stories, read stories, feed/page fetch histories, and proxied sites. - * [PostgreSQL](http://www.postgresql.com): Relational database, used to store feeds, - subscriptions, and user accounts. - * [Redis](http://redis.io): Programmer's database, used to assemble stories for the river, store story ids, manage feed fetching schedules, and the minuscule bit of caching that NewsBlur uses. - * [Elasticsearch](http://elasticsearch.org): Search database, use for searching stories. Optional. - +- [Python 3.7+](http://www.python.org): The language of choice. +- [Django](http://www.djangoproject.com): Web framework written in Python, used + to serve all pages. +- [Celery](http://ask.github.com/celery) & [RabbitMQ](http://www.rabbitmq.com): + Asynchronous queueing server, used to fetch and parse RSS feeds. +- [MongoDB](http://www.mongodb.com), [Pymongo](https://pypi.python.org/pypi/pymongo), & + [Mongoengine](http://www.github.com/hmarr/mongoengine): Non-relational database, + used to store stories, read stories, feed/page fetch histories, and proxied sites. +- [PostgreSQL](http://www.postgresql.com): Relational database, used to store feeds, + subscriptions, and user accounts. +- [Redis](http://redis.io): Programmer's database, used to assemble stories for the river, store story ids, manage feed fetching schedules, and the minuscule bit of caching that NewsBlur uses. +- [Elasticsearch](http://elasticsearch.org): Search database, use for searching stories. Optional. + ### Client-side and design - * [jQuery](http://www.jquery.com): Cross-browser compliant JavaScript code. IE works without effort. - * [Underscore.js](http://underscorejs.org/): Functional programming for JavaScript. - Indispensable. - * [Backbone.js](http://backbonejs.org/): Framework for the web app. Also indispensable. - * Miscellaneous jQuery Plugins: Everything from resizable layouts, to progress - bars, sortables, date handling, colors, corners, JSON, animations. - [See the complete list](https://github.com/samuelclay/NewsBlur/tree/master/media/js). - +- [jQuery](http://www.jquery.com): Cross-browser compliant JavaScript code. IE works without effort. +- [Underscore.js](http://underscorejs.org/): Functional programming for JavaScript. + Indispensable. +- [Backbone.js](http://backbonejs.org/): Framework for the web app. Also indispensable. +- Miscellaneous jQuery Plugins: Everything from resizable layouts, to progress + bars, sortables, date handling, colors, corners, JSON, animations. + [See the complete list](https://github.com/samuelclay/NewsBlur/tree/master/media/js). ### Prerequisites + * Docker * Docker-compose ## Installation Instructions - 1. Clone this repo - 2. Run `make nb` to build all of the NewsBlur containers. This will set up all necessary databases, front-end django apps, celery tasks, node apps, flask database monitor and metrics, nginx, and a haproxy load balancer. - 7. Navigate to: + +1. Clone this repo +2. Run `make nb` to build all of the NewsBlur containers. This will set up all necessary databases, front-end django apps, celery tasks, node apps, flask database monitor and metrics, nginx, and a haproxy load balancer. +3. Navigate to: https://localhost @@ -63,34 +64,34 @@ ## Using a custom domain - 1. Run the custom domain script - +1. Run the custom domain script + ``` bash ./utils/custom_domain.sh ``` - + This script will do the following: - * Change `NEWSBLUR_URL` and `SESSION_COOKIE_DOMAIN` in `newsblur_web/docker_local_settings.py` - * Change the domain in `config/fixtures/bootstrap.json` - - You can also change domains: `bash ./utils/custom_domain.sh ` - - 2. If you're using a custom subdomain, you'll also want to add it to `ALLOWED_SUBDOMAINS` in `apps/reader/views.py` + - Change `NEWSBLUR_URL` and `SESSION_COOKIE_DOMAIN` in `newsblur_web/docker_local_settings.py` + - Change the domain in `config/fixtures/bootstrap.json` - 3. A way to make sure you updated all the correct places: +You can also change domains: `bash ./utils/custom_domain.sh ` - * Go to the website address in your browser - * Open developer tools and look at the network tab - * Try to login - * Look again at the developer tools, there should be a POST call to /login - * Observe the Response headers for that call - * The value of the "set-cookie" header should contain a "Domain=" string +2. If you're using a custom subdomain, you'll also want to add it to `ALLOWED_SUBDOMAINS` in `apps/reader/views.py` + +3. A way to make sure you updated all the correct places: + + - Go to the website address in your browser + - Open developer tools and look at the network tab + - Try to login + - Look again at the developer tools, there should be a POST call to /login + - Observe the Response headers for that call + - The value of the "set-cookie" header should contain a "Domain=" string If the string after `Domain=` is not the domain you are using to access the website, then your configuration still needs your custom domain. - + You can also confirm that there is a domain name mismatch in the database by running `make shell` & typing `Site.objects.all()[0]` to show the domain that NewsBlur is expecting. - + ## Making docker-compose work with your existing database To make docker-compose work with your database, upgrade your local database to the docker-compose version and then volumize the database data path by changing the `./docker/volumes/` part of the volume directive in the service to point to your local database's data directory. @@ -99,16 +100,17 @@ To make docker-compose work with an older database version, change the image ver ## Contribution Instructions -* Making Changes: - * To apply changes to the Python or JavaScript code, use the `make` command. - * To apply changes to the docker-compose.yml file, use the `make rebuild` command. - * To apply changes to the docker/haproxy/haproxy.conf file, node packages, or any new database migrations you will need to use the `make nb` command. +- Making Changes: -* Adding Python packages: - Currently, the docker-compose.yml file uses the newsblur/newsblur_python3 image. It is built using the Dockerfile found in `docker/newsblur_base_image.Dockerfile`. Because of how the docker image is set up, you will need to create your own image and direct your docker-compose.yml file to use it. Please follow the following steps to do so. + - To apply changes to the Python or JavaScript code, use the `make` command. + - To apply changes to the docker-compose.yml file, use the `make rebuild` command. + - To apply changes to the docker/haproxy/haproxy.conf file, node packages, or any new database migrations you will need to use the `make nb` command. - 1. Add your new site-packages to config/requirements.txt. - 2. Add the following lines of code to your docker-compose.yml file to replace anywhere where it says `image: newsblur/newsblur_python3` +- Adding Python packages: + Currently, the docker-compose.yml file uses the newsblur/newsblur_python3 image. It is built using the Dockerfile found in `docker/newsblur_base_image.Dockerfile`. Because of how the docker image is set up, you will need to create your own image and direct your docker-compose.yml file to use it. Please follow the following steps to do so. + + 1. Add your new site-packages to config/requirements.txt. + 2. Add the following lines of code to your docker-compose.yml file to replace anywhere where it says `image: newsblur/newsblur_python3` build: @@ -116,14 +118,15 @@ To make docker-compose work with an older database version, change the image ver dockerfile: docker/newsblur_base_image.Dockerfile - 3. Run the `make nb` command to rebuild your docker-compose containers + 3. Run the `make nb` command to rebuild your docker-compose containers -* Debugging Python - * To debug your code, drop `import pdb; pdb.set_trace()` into the Python code where you would like to start debugging +- Debugging Python + + - To debug your code, drop `import pdb; pdb.set_trace()` into the Python code where you would like to start debugging and run `make` and then `make debug`. -* Using Django shell within Docker - * Make sure your docker containers are up and run `make shell` to open +- Using Django shell within Docker + - Make sure your docker containers are up and run `make shell` to open the Django shell within the newsblur_web container. ### Running unit and integration tests @@ -139,16 +142,16 @@ Performance tests use the locust performance testing tool. To run performance te `make perf-cli users=1 rate=1 host=https://localhost`. Feel free to change the users, rate, and host variables in the command to meet you needs. -You can also run locust performance tests using a UI by running `make perf-ui` and then navigating to +You can also run locust performance tests using a UI by running `make perf-ui` and then navigating to http://127.0.0.1:8089. This allows you to chart and export your performance data. To run locust using docker, just run `make perf-docker` and navigate to http://127.0.0.1:8089 ## Author - * Created by [Samuel Clay](http://www.samuelclay.com). - * Email address: - * [@samuelclay](http://twitter.com/samuelclay) on Twitter. +- Created by [Samuel Clay](https://www.samuelclay.com). +- Email address: +- [@samuelclay](https://x.com/samuelclay) on X/Twitter. ## License diff --git a/apps/newsletters/amazon-ses-lambda.py b/apps/newsletters/amazon-ses-lambda.py new file mode 100644 index 000000000..fc7decd34 --- /dev/null +++ b/apps/newsletters/amazon-ses-lambda.py @@ -0,0 +1,34 @@ +import json +import requests +import boto3 +import email + + +def lambda_handler(event, context): + # Get the message ID for the email + message_id = event["Records"][0]["ses"]["mail"]["messageId"] + + # Retrieve the email content from S3 if configured to store + s3_client = boto3.client("s3") + bucket_name = "newsblur-email-logs" + email_data = s3_client.get_object(Bucket=bucket_name, Key=message_id) + raw_email = email_data["Body"].read().decode("utf-8") + + # Parse the raw email + parsed_email = email.message_from_string(raw_email) + + # Prepare the payload for the webhook + # Include original recipient + payload = { + "from": parsed_email["From"], + "to": parsed_email["To"], + "subject": parsed_email["Subject"], + "body": parsed_email.get_payload(), + "original_recipient": parsed_email["X-Original-Recipient"], + } + + # Send to webhook + webhook_url = "https://push.newsblur.com/newsletters/receive/" + response = requests.post(webhook_url, json=payload) + + return {"statusCode": response.status_code, "body": json.dumps("Email forwarded to webhook")} diff --git a/media/css/pages/welcome.css b/media/css/pages/welcome.css index aec9eb6b6..545058613 100644 --- a/media/css/pages/welcome.css +++ b/media/css/pages/welcome.css @@ -169,7 +169,7 @@ height: 300px; position: absolute; bottom: -350px; - right: -40px; + right: 0; border-radius: 2px; border-top-left-radius: 4px; border-top-right-radius: 4px; @@ -180,7 +180,7 @@ height: 300px; position: absolute; bottom: -300px; - right: 0; + right: -80px; border-radius: 2px; margin-right: 100px; border-top-left-radius: 4px; diff --git a/media/img/iphone/Sketch-AppStore-Shots-2.2.sketch b/media/img/iphone/Sketch-AppStore-Shots-2.2.sketch index ca460c028..d755b13ca 100755 Binary files a/media/img/iphone/Sketch-AppStore-Shots-2.2.sketch and b/media/img/iphone/Sketch-AppStore-Shots-2.2.sketch differ diff --git a/media/img/iphone/iphone-16.png b/media/img/iphone/iphone-16.png new file mode 100644 index 000000000..34f2c6176 Binary files /dev/null and b/media/img/iphone/iphone-16.png differ diff --git a/media/img/welcome/header-ios-original.png b/media/img/welcome/header-ios-original.png deleted file mode 100644 index dea4d1106..000000000 Binary files a/media/img/welcome/header-ios-original.png and /dev/null differ diff --git a/media/img/welcome/header-ios.png b/media/img/welcome/header-ios.png deleted file mode 100644 index 4ce48e651..000000000 Binary files a/media/img/welcome/header-ios.png and /dev/null differ diff --git a/media/img/welcome/subfeature_10.png b/media/img/welcome/subfeature_10.png index 2855ba14b..26efd865c 100644 Binary files a/media/img/welcome/subfeature_10.png and b/media/img/welcome/subfeature_10.png differ diff --git a/media/img/welcome/welcome-android.png b/media/img/welcome/welcome-android.png new file mode 100644 index 000000000..c6eb16173 Binary files /dev/null and b/media/img/welcome/welcome-android.png differ diff --git a/media/img/welcome/welcome-ios.png b/media/img/welcome/welcome-ios.png new file mode 100644 index 000000000..d92f57437 Binary files /dev/null and b/media/img/welcome/welcome-ios.png differ diff --git a/media/img/welcome/welcome-mac.png b/media/img/welcome/welcome-mac.png new file mode 100644 index 000000000..433bebb70 Binary files /dev/null and b/media/img/welcome/welcome-mac.png differ diff --git a/media/js/newsblur/reader/reader.js b/media/js/newsblur/reader/reader.js index 9433ab7fd..d132a6762 100644 --- a/media/js/newsblur/reader/reader.js +++ b/media/js/newsblur/reader/reader.js @@ -2659,7 +2659,7 @@ send_story_to_twitter: function (story_id) { var story = this.model.get_story(story_id); - var url = 'https://twitter.com/intent/tweet'; + var url = 'https://x.com/intent/post'; var twitter_url = [ url, '?text=', diff --git a/media/js/newsblur/reader/reader_tutorial.js b/media/js/newsblur/reader/reader_tutorial.js index 9acd21772..061588046 100644 --- a/media/js/newsblur/reader/reader_tutorial.js +++ b/media/js/newsblur/reader/reader_tutorial.js @@ -281,11 +281,11 @@ _.extend(NEWSBLUR.ReaderTutorial.prototype, { $.make('div', { className: 'NB-page NB-page-5' }, [ $.make('h4', 'Stay connected to NewsBlur on Twitter'), $.make('div', { className: 'NB-tutorial-twitter' }, [ - $.make('a', { className: 'NB-splash-link', href: 'http://twitter.com/samuelclay', target: '_blank' }, [ + $.make('a', { className: 'NB-splash-link', href: 'https://x.com/samuelclay', target: '_blank' }, [ $.make('img', { src: NEWSBLUR.Globals.MEDIA_URL + '/img/static/Samuel%20Clay%20sq.jpg', style: 'border-color: #505050;' }), $.make('span', '@samuelclay') ]), - $.make('a', { className: 'NB-splash-link', href: 'http://twitter.com/newsblur', target: '_blank' }, [ + $.make('a', { className: 'NB-splash-link', href: 'http://x.com/newsblur', target: '_blank' }, [ $.make('img', { src: NEWSBLUR.Globals.MEDIA_URL + '/img/logo_128.png' }), $.make('span', '@newsblur') ]) diff --git a/templates/502.html b/templates/502.html index ee854855d..b867b23b6 100644 --- a/templates/502.html +++ b/templates/502.html @@ -67,7 +67,7 @@

502 · NewsBlur is down

Please wait patiently while NewsBlur comes back.

-

@newsblur on Twitter may have more information.

+

@newsblur on X/Twitter may have more information.

diff --git a/templates/502.http b/templates/502.http index 2be52389b..7a69d5365 100644 --- a/templates/502.http +++ b/templates/502.http @@ -72,7 +72,7 @@ Content-Type: text/html

502 · NewsBlur is down

Please wait patiently until NewsBlur comes back.

-

@newsblur on Twitter may have more information.

+

@newsblur on X/Twitter may have more information.

diff --git a/templates/reader/footer.xhtml b/templates/reader/footer.xhtml index 5178b3a8a..cee4ed794 100644 --- a/templates/reader/footer.xhtml +++ b/templates/reader/footer.xhtml @@ -5,11 +5,11 @@ - + - + - +
- +
- +
- +
@@ -197,9 +197,9 @@
Regularly used searches are conveniently given their own feeds
- -
First-class iOS App
-
The NewsBlur iOS app is free and is jam-packed with features
+ +
Native iOS/macOS Apps
+
The NewsBlur iOS and macOS apps are free and jam-packed with features
@@ -207,7 +207,7 @@
The original story from truncated RSS feeds is seamlessly expanded
- +
First-class Android App
The NewsBlur Android app is free and has it all
@@ -238,7 +238,7 @@
-
Twitter & YouTube
+
YouTube
Even sites that don't publish RSS feeds can be followed
@@ -362,11 +362,11 @@