Skip to content
This repository was archived by the owner on Mar 9, 2024. It is now read-only.

Commit 289d1f3

Browse files
orcutt989mre
authored andcommitted
use python 3.6 typing (#33)
all variables and functions are now typed in order to help with refactoring
1 parent 2d411b9 commit 289d1f3

File tree

4 files changed

+59
-58
lines changed

4 files changed

+59
-58
lines changed

timelapse/__main__.py

Lines changed: 37 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,55 +11,55 @@
1111
from Foundation import NSUserDefaults
1212

1313

14-
def dark_mode():
14+
def dark_mode() -> bool:
1515
return NSUserDefaults.standardUserDefaults().stringForKey_('AppleInterfaceStyle') == "Dark"
1616

1717

1818
# Configuration
19-
start_recording = False # Start recording on launch
20-
encode = True # Create video after recording
21-
screenshot_interval = 1.5 # Number of seconds between screenshots
22-
dir_base = os.path.expanduser("~") # Base directory
23-
dir_app = "timelapse" # Output directory
24-
dir_pictures = "Pictures" # Place for pictures in filesystem
25-
dir_movies = "Movies" # Place for movies in filesystem
26-
dir_resources = "./resources/"
19+
start_recording: bool = False # Start recording on launch
20+
encode: bool = True # Create video after recording
21+
screenshot_interval: float = 1.5 # Number of seconds between screenshots
22+
dir_base: str = os.path.expanduser("~") # Base directory
23+
dir_app: str = "timelapse" # Output directory
24+
dir_pictures: str = "Pictures" # Place for pictures in filesystem
25+
dir_movies: str = "Movies" # Place for movies in filesystem
26+
dir_resources: str = "./resources/"
2727
if dark_mode():
2828
dir_resources += "white"
2929
else:
3030
dir_resources += "black"
3131

32-
subdir_suffix = "Session-" + time.strftime("%Y%m%d") # Name of subdirectory
33-
image_recording = "record.gif" # App icon recording
34-
image_idle = "stop.gif" # App icon idle
35-
create_session_subdir = True # New screenshot directory for each session
36-
create_movies = True # Create movies from screenshots after recording
32+
subdir_suffix: str = "Session-" + time.strftime("%Y%m%d") # Name of subdirectory
33+
image_recording: str = "record.gif" # App icon recording
34+
image_idle: str = "stop.gif" # App icon idle
35+
create_session_subdir: str = True # New screenshot directory for each session
36+
create_movies: bool = True # Create movies from screenshots after recording
3737
# Menu item text when recorder is running
38-
text_recorder_running = "Stop recording"
39-
text_recorder_idle = "Start recording" # Menu item text when recorder is idle
38+
text_recorder_running: str = "Stop recording"
39+
text_recorder_idle: str = "Start recording" # Menu item text when recorder is idle
4040
# Tooltip of menu icon when not recording
41-
tooltip_idle = "Timelapse screen recorder"
42-
tooltip_running = "Recording | " + tooltip_idle # Tooltip when recording
41+
tooltip_idle: str = "Timelapse screen recorder"
42+
tooltip_running: str = "Recording | " + tooltip_idle # Tooltip when recording
4343

4444

4545
###############
4646

4747
class Timelapse(NSObject):
4848
""" Creates a timelapse video """
4949

50-
def applicationDidFinishLaunching_(self, notification):
50+
def applicationDidFinishLaunching_(self, notification) -> None:
5151
self.check_dependencies()
5252

5353
# Initialize recording
54-
self.recording = start_recording
54+
self.recording: bool = start_recording
5555
self.recorder = None
5656

5757
# Set correct output paths
58-
self.recorder_output_basedir = os.path.join(
58+
self.recorder_output_basedir: str = os.path.join(
5959
dir_base, dir_pictures, dir_app)
60-
self.encoder_output_basedir = os.path.join(dir_base, dir_movies)
60+
self.encoder_output_basedir: str = os.path.join(dir_base, dir_movies)
6161

62-
self.image_dir = self.create_dir(self.recorder_output_basedir)
62+
self.image_dir: str = self.create_dir(self.recorder_output_basedir)
6363

6464
# Create a reference to the statusbar (menubar)
6565
self.statusbar = NSStatusBar.systemStatusBar()
@@ -77,13 +77,13 @@ def applicationDidFinishLaunching_(self, notification):
7777
self.loadIcons()
7878
self.setStatus()
7979

80-
def loadIcons(self):
80+
def loadIcons(self) -> None:
8181
self.icon_recording = NSImage.alloc().initWithContentsOfFile_(
8282
os.path.join(dir_resources, image_recording))
8383
self.icon_idle = NSImage.alloc().initWithContentsOfFile_(
8484
os.path.join(dir_resources, image_idle))
8585

86-
def setStatus(self):
86+
def setStatus(self) -> None:
8787
""" Sets the image and menu text according to recording status """
8888
if self.recording:
8989
self.statusitem.setImage_(self.icon_recording)
@@ -94,7 +94,7 @@ def setStatus(self):
9494
self.recordButton.setTitle_(text_recorder_idle)
9595
self.statusitem.setToolTip_(tooltip_idle)
9696

97-
def createMenu(self):
97+
def createMenu(self) -> menu:
9898
""" Status bar menu """
9999
menu = NSMenu.alloc().init()
100100
# Bind record event
@@ -107,7 +107,7 @@ def createMenu(self):
107107
menu.addItem_(menuitem)
108108
return menu
109109

110-
def startStopRecording_(self, notification):
110+
def startStopRecording_(self, notification) -> None:
111111
if self.recording:
112112
self.recorder.join(timeout=screenshot_interval*2)
113113
# Create timelapse after recording?
@@ -119,18 +119,18 @@ def startStopRecording_(self, notification):
119119
notify("Timelapse started", "The recording has started")
120120
self.recorder = Recorder(self.image_dir, screenshot_interval)
121121
self.recorder.start()
122-
self.recording = not self.recording
122+
self.recording: bool = not self.recording
123123
self.setStatus()
124124

125125
@objc.python_method
126-
def create_dir(self, base_dir):
126+
def create_dir(self, base_dir: str) -> str:
127127
""" Creates a specified directory and the path to it if necessary """
128128
if create_session_subdir:
129129
# Create a new subdirectory
130-
output_dir = os.path.join(base_dir, self.get_sub_dir(base_dir))
130+
output_dir: str = os.path.join(base_dir, self.get_sub_dir(base_dir))
131131
else:
132132
# Don't create a subdirectory. Use base directory for output
133-
output_dir = base_dir
133+
output_dir: str = base_dir
134134
# Create path if it doesn't exist
135135
try:
136136
print(f"Output directory: {output_dir}")
@@ -144,20 +144,20 @@ def create_dir(self, base_dir):
144144
return output_dir
145145

146146
@objc.python_method
147-
def get_sub_dir(self, base_dir):
147+
def get_sub_dir(self, base_dir: str) -> str:
148148
""" Returns the next nonexistend subdirectory to base_dir """
149-
subdir_base = os.path.join(base_dir, subdir_suffix)
149+
subdir_base: str = os.path.join(base_dir, subdir_suffix)
150150
# Check if we can use subdir without any session id
151-
subdir = subdir_base
151+
subdir: str = subdir_base
152152
# Use a session id only if subdir already exists
153-
session_number = 0
153+
session_number: int = 0
154154
while os.path.exists(subdir):
155155
# We can't use subdir. Create directory with session id
156156
session_number += 1
157-
subdir = subdir_base + "-" + str(session_number)
157+
subdir: str = subdir_base + "-" + str(session_number)
158158
return subdir
159159

160-
def check_dependencies(self):
160+
def check_dependencies(self) -> None:
161161
try:
162162
subprocess.run(['ffmpeg'], check=True,
163163
capture_output=True, timeout=10.0)

timelapse/encoder.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import fnmatch
77
import shutil
88
from notify import notify # Shows notifications/alerts
9+
from typing import List
910

1011
not_found_msg = """
1112
The ffmpeg command was not found;
@@ -18,30 +19,30 @@
1819
class Encoder(Thread):
1920
"""Create a video file from images"""
2021

21-
def __init__(self, input_dir, output_dir):
22+
def __init__(self, input_dir: str, output_dir: str) -> None:
2223
# Initialize the thread
2324
Thread.__init__(self)
2425

2526
# Set config options
26-
self.input = f"{input_dir}/%d.png"
27-
timestamp = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
28-
self.output = f"{output_dir}/timelapse-{timestamp}.mov"
27+
self.input: str = f"{input_dir}/%d.png"
28+
timestamp: str = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
29+
self.output: str = f"{output_dir}/timelapse-{timestamp}.mov"
2930

3031
print("Encoder started")
3132

32-
def join(self, timeout=None):
33+
def join(self, timeout=None) -> None:
3334
""" Hard shutdown """
3435
Thread.join(self)
3536

36-
def run(self):
37+
def run(self) -> None:
3738
"""
3839
Now that we have screenshots of the user's desktop, we will stitch them
3940
together using `ffmpeg` to create a movie. Each image will become
4041
a single frame in the movie.
4142
"""
4243
# Call ffmpeg with settings compatible with QuickTime.
4344
# https://superuser.com/a/820137
44-
command = ["/usr/local/bin/ffmpeg", "-y",
45+
command: List[str]= ["/usr/local/bin/ffmpeg", "-y",
4546
"-framerate", "30",
4647
"-i", self.input,
4748
"-vf", "format=yuv420p",

timelapse/notify.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22

33

4-
def notify(title, text):
4+
def notify(title: str, text: str) -> int:
55
os.system("""
66
osascript -e 'display notification "{}" with title "{}"'
77
""".format(text, title))

timelapse/recorder.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from AppKit import NSEvent, NSScreen, NSMouseInRect
77

88

9-
def get_screen_with_mouse_index():
9+
def get_screen_with_mouse_index() ->int:
1010
mouseLocation = NSEvent.mouseLocation()
1111
screens = NSScreen.screens()
1212
for i, screen in enumerate(screens):
@@ -20,7 +20,7 @@ class Recorder(Process):
2020
Takes a screenshot every 'interval' seconds and saves it into output_dir or a subdirectory thereof.
2121
"""
2222

23-
def __init__(self, output_dir, interval=4):
23+
def __init__(self, output_dir: str, interval: int=4) -> None:
2424
# Initialize the thread
2525
Process.__init__(self)
2626

@@ -29,42 +29,42 @@ def __init__(self, output_dir, interval=4):
2929
self._stopped = Event()
3030

3131
# Set config options
32-
self.output_dir = output_dir
33-
self.interval = interval
34-
self.format = "png"
32+
self.output_dir: str = output_dir
33+
self.interval: int = interval
34+
self.format: str = "png"
3535

3636
# Number of screenshots taken
37-
self.screenshot_counter = 0
37+
self.screenshot_counter: int = 0
3838
print("Recorder started")
3939

40-
def join(self, timeout=None):
40+
def join(self, timeout=None) -> None:
4141
""" Stop recording """
4242
self._stop.set()
4343
self._stopped.wait()
4444
print("Recorder stopped. Total recording time: " +
4545
self.get_recording_time() + ".")
4646
Process.join(self, timeout=timeout)
4747

48-
def run(self):
48+
def run(self) -> None:
4949
""" Periodically take a screenshots of the screen """
5050
while not self._stop.is_set():
5151
self.screenshot()
5252
self._stop.wait(self.interval)
5353

5454
self._stopped.set()
5555

56-
def get_recording_time(self):
56+
def get_recording_time(self) ->str:
5757
return str(self.screenshot_counter * self.interval) + " seconds"
5858

59-
def get_filename(self):
59+
def get_filename(self) ->str:
6060
""" Call screencapture for mac screenshot """
61-
filename = os.path.join(
61+
filename: str = os.path.join(
6262
self.output_dir, f"{self.screenshot_counter}.{self.format}")
6363
return filename
6464

65-
def screenshot(self):
65+
def screenshot(self) -> None:
6666
""" This method uses Mac OSX screencapture from the commandline """
67-
filename = self.get_filename()
67+
filename: str = self.get_filename()
6868
subprocess.run(
6969
['screencapture', '-S', '-o', '-x', '-D',
7070
str(get_screen_with_mouse_index() + 1), '-t', self.format, filename],

0 commit comments

Comments
 (0)