Skip to content

🎧 A small iOS app for e.g. iPhone that allow you to add links heard in podcasts into reminders

License

Notifications You must be signed in to change notification settings

engdan77/memocast

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Memocast πŸ“» βœ…

An iOS app (or script perhaps better term) for e.g. iPhone that allow you to add links heard in podcasts into reminders.

Motivation πŸ€”

Imagine that you just as I often do listening to a podcast such as PythonBytes (a fantastic one btw) using Pocket Casts while out walking and hear a talk about an interesting project or article you wish to read more about when time allow.

Thankfully the referenced links are added to the show notes of the talk, but it means you would usually need to look it up on the podcasts main page and add this into your own personal notes, and using the phone to copy-and-paste is found tedious.

Wouldn't it be nice if there was an easier way select which of those you found interesting and have them added to reminders on your phone while you'd still out walking without the need to lose too much of your focus on where you put your feets..?

... if you also see this as a problem and wished there were a better way, then this small app might be what you're searching for.

How to use πŸ‘¨πŸΌβ€πŸ«πŸ“±

Once you've listened to your podcast using Google podcaster you click "share" and "Run Pythonista script"
You will then have a MemoCast icon, click this and it will allow you select the links you wish to add to your Reminders app for later use.
usage

Currently supported podcasts 🎧

So currently the following podcasts are currently supported by the parsers that does the work of finding links and allow one to add to your reminders, but easily extended in the futurue ... see further down how ...

Releases πŸ’Ύ

The initial Memocast <= 1.0.0 were relying on Google Podcast, but since the turndown πŸͺ¦ 2024 the future releases instead suppors same method but you share from Pocket Casts instead.

Project highlighted ⭐️

If you wish to listen or see discussion around this project you may in interessted visiting PythonBytes #338: Scripting iOS with Python (at 18:20) and Real Python - episode 160 (at 43:20)

Installation βœ“

Step 1) Install Pythonista 3 from app store

Step 2) Either download and run this install.py script within Pythonista on your iPhone/iPad or aim your camera at the below QR-code and open this link.

qr_install_memocastinstall_procedure

Step 3) Click Run in the upper right corner.

Step 4) Open up Pyhonista ➑ Script Library ➑ This Phone ➑ memocast-master ➑ app.py

Step 5) Click on the wrench πŸ”§ in the upper right ➑ Shortcuts ➑ Share Extension ➑ Click on + icon

Step 6) Change custom title to "MemoCast" ➑ click Add

Develop support for additional podcasts

Create the code

All that is needed need to do is to create a new python file within the parsers package...

πŸ“¦ memocast-project
┣ πŸ“‚ memocast
┃ ┣ πŸ“œ ...
┃ β”— πŸ“‚ parsers
┃   ┣ πŸ“œ __init__.py
┃   ┣ πŸ“œ baseclass.py
┃   ┣ πŸ“œ pythonbytes.py
┃   β”— πŸ“œ otherpodcast.py  βœ¨πŸ†•

... let's pretend we wish to add a new one named otherpodcast.py and within this we assure we create a new class and inherit from BasePodCastParser that will allow the application to dynamically use this new one as a plugin.

# memocast/parsers/otherpodcast.py

from typing import Iterable
from bs4 import BeautifulSoup  # Most likely to be used for parsing HTML
from memocast.logging_ import logger  # Custom logging singleton class
from .. import io_  # Module with e.g. convinient download_html(episode_url)
from .. import protocols  # Includes dataclass Url
from .baseclass import BasePodcastParser  # Inherit from this baseclass


class OtherParser(BasePodcastParser):
  	# This is the URL of which this podcast has its links available
    base_url = 'https://.....'  

    @staticmethod
    def get_podcast_short_name() -> str:
        return "OtherPodCast"  # This is used as part of the links shown in Reminders

   def get_current_episode_number(self) -> int:
    # This should return the episode number from Google Podcasts URL
    example_episode_number = 134
    return example_episodr_number
      
    def parse(self) -> Iterable[protocols.Url]:
      # This is the main method to do the work
      episode_source_html = io_.download('https://....')  # Example
      bs = BeautifulSoup(episode_source_html, 'html.parser')
        static_example_urls = [
          protocols.Url(url='http://foo.com', description='Project Foo', parser=self)
          protocols.Url(url='http://bar.com', description='Project Bar', parser=self)
        ]  # Obviously this should be dynamically created by your code
        return static_example_urls  # Return a list of URLs

By adding this module it will work as a plugin and will automatically be used by the app.

Test your code

To manually test your parser you can also do that using your regular working environment (MacOS/Windows/Linux) by copying the URL to your clipboard since it use this as fallback. Currently the user interface and "Reminders" is only support by iOS the application will exit before then - but for most cases enough to test your parser.

As with good best practice you may consider creating unit tests (pytest) within the tests folder.

My development workflow and reflections using Pythonista πŸ‘¨πŸΌβ€πŸ’»

My past experience developing apps for iOS using Python have been that it have added a lot of overhead using framework such as Kivy that have involved setting up certain tool chain including XCode and required one to compile such into an .ipa file that also required a complex procedure for signing and/or apply other strategy to allow other users to take advantage of your app that often came with a price (at least at that time). But such project were eventually made such as this one.

When I stumbled on Pythonista 3 it crossed me how easy it was to get an "app" running with minimal efforts and does expose the most relevant iOS API's such as accessing part of it you wouldn't easily do using other frameworks and it does have a rich set of packages included from start such as those found here which is quite astonishing. And have yet only started to scratch the surface. πŸ˜€πŸ‘

And all that is needed is to share your Python code that also could be done sharing as an URL (at least small scripts) that makes it relatively easy to share your project.

Pythonista 3 comes with a one-time price, but a fairly low one so I would not think it would frighten others

Also what I did discover and made the development experience so smooth is the fact that as long as you have a Mac with a silicon processor you are apple to install and run Pythonista as iOS app within MacOS and continue developing using your favorite IDE (such as PyCharm) and interchangable run within Pythonista on your computer as found needed (acting as an "emulator").

So what I did was to create project folder within the Pythonista created in the iCloud drive, and then I also assured I had this folder under version control using a git-repository and using the iOS app Working Copy as git client on the devices.

Now this iCloud folder that you can have kept synced with your MacOS is found available within Library/Mobile Documents/iCloud~com~omz-software~Pythonista3/Documents so that way you can access it either from your favorite IDE on your Mac or from Pythonista from you iOS devices.

For me at least this satisifed my main needs... πŸ™Œ

Software design

High Level Design 🚁

Essentially in sequence the application does ..

  • Get URL for the Pocket Casts
  • The BasePodCastParser sequentially test all parsers
    • If multiple parsers matching give user a choice to select correct
  • The list of all links (URLs) with descriptions displayed to user for selection
  • Selected links stored to iOS Reminders
flowchart LR
    subgraph get_url [Get Pockets Casts URL]
        direction LR
        ios_share -.-> get_html_source
        clipboard -.-> get_html_source
    end
    
    subgraph process [Get podcast homepage and parse]
        get_html_source --> get_links
        get_links -- ".try_all()" --> PodCastParser(BasePodCastParser)
        PodCastParser --Urls--> get_links
        style PodCastParser fill:#bbf
    end

    subgraph podcast [External]
        external_podcast_page -.-> PodCastParser

    end

    subgraph select [Display & Select links]
        get_links -- Urls --> PythonistaPodView 
        style PythonistaPodView fill:#bbf    
    end

    subgraph save [Save to Reminders]
        PythonistaPodView -- Urls --> Reminders[(iOS Reminders)]
    end
Loading

Class diagram over main pieces 🧩

For further development this is the the only class of relevance to extend with additional parsers

classDiagram
    BasePodcastParser <|-- PythonBytesParser
    BasePodcastParser <|-- OtherParser
    BasePodView <|-- PythonistaPodView
    main ..> PythonistaPodView : depends
    main ..> BasePodcastParser : depends

class BasePodcastParser {
    <<abstract>>
    +try_all()
    }

class PythonBytesParser {
    + base_url
    - get_podcast_short_name() : str
    - get_current_episode_number() : int
    + parse() : List[Url]
    }

class OtherParser {
    + base_url
    - get_podcast_short_name() : str
    - get_current_episode_number() : int
    + parse() : List[Url]
    }

class BasePodView {
    <<abstract>>
    +show(urls: List[Url])
    add_urls_to_reminder(urls: List[Url])
    get_option(self, options: List[str], title='')
}

class PythonistaPodView {
    ...
}

class main {
    ...
}
Loading

Contributions 🫢

This is a project in a very early stage and any contributions are more than welcome by submitting pull request for the repository https://github.com/engdan77/memocast since it may still have some rough edges. And new "parsers" (see above) is found valuable.

✨ Credits goes to ..

About

🎧 A small iOS app for e.g. iPhone that allow you to add links heard in podcasts into reminders

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages