Skip to content

Commit

Permalink
Merge pull request #2 from exelban/dev
Browse files Browse the repository at this point in the history
v1.2.0
  • Loading branch information
exelban authored Jun 26, 2019
2 parents 8b8b120 + 9119b20 commit 613568d
Show file tree
Hide file tree
Showing 22 changed files with 1,320 additions and 52 deletions.
27 changes: 16 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ Simple macOS system monitor in your menu bar

[<img src="https://serhiy.s3.eu-central-1.amazonaws.com/Github_repo/stats/widgets%3Fv1.1.0.1.png">](https://github.com/exelban/stats/releases)

## Why
## Features
Stats is a application which allows you to monitor your macOS system.
Also its:

- free
- easy to use
- no advertisement
- no tracking
- few types of widgets
- black theme compatible
- CPU Usage
- Memory Usage
- Disk utilization
- Battery level
- Network usage
- Black theme compatible

## Installation
You can download latest version [here](https://github.com/exelban/stats/releases).
Expand All @@ -23,8 +22,9 @@ You can download latest version [here](https://github.com/exelban/stats/releases
| --- | --- | --- |
| **CPU** | Percentage / Chart / Chart with value | Shows CPU usage |
| **Memory** | Percentage / Chart / Chart with value | Shows RAM usage |
| **Disk** | Percentage | Shows disk filling |
| **Disk** | Percentage | Shows disk utilization |
| **Battery** | Graphic / Percentage | Shows battery level and charging status |
| **Newtork** | Dots / Upload/Download traffic | Shows network activity |

## Compatibility
| macOS | Compatible |
Expand All @@ -41,14 +41,19 @@ You can download latest version [here](https://github.com/exelban/stats/releases
- [ ] temperature module
- [X] battery module
- [X] move to module system (CPU, RAM, DISK)
- [ ] network module
- [X] network module
- [X] save settings
- [ ] OTA updates
- [X] charts
- [X] autostart on boot

## What's new

### v1.2.0
- added network module
- added Check for updates window
- fixed few bugs

### v1.1.0
- added battery module
- added chart widget for CPU and Memory
Expand All @@ -58,4 +63,4 @@ You can download latest version [here](https://github.com/exelban/stats/releases
- first release

## License
[GNU General Public License](https://github.com/exelban/stats/blob/master/LICENSE)
[MIT License](https://github.com/exelban/stats/blob/master/LICENSE)
45 changes: 43 additions & 2 deletions Stats.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@
9A09C8A222B3D94D0018426F /* BatteryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A09C8A122B3D94D0018426F /* BatteryView.swift */; };
9A1410F9229E721100D29793 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A1410F8229E721100D29793 /* AppDelegate.swift */; };
9A141100229E721200D29793 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A1410FE229E721200D29793 /* Main.storyboard */; };
9A426DB822C2B5EE00C064C4 /* macAppUpdater.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A426DB722C2B5EE00C064C4 /* macAppUpdater.swift */; };
9A426DBE22C2BE0000C064C4 /* Updates.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9A426DBD22C2BE0000C064C4 /* Updates.storyboard */; };
9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A18422A1D26D0033E318 /* MenuBar.swift */; };
9A57A19B22A1E1C50033E318 /* Module.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A19A22A1E1C50033E318 /* Module.swift */; };
9A57A19D22A1E3270033E318 /* CPU.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A57A19C22A1E3270033E318 /* CPU.swift */; };
9A58D1B022C150C800405315 /* Network.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58D1AF22C150C800405315 /* Network.swift */; };
9A58D1B222C150D700405315 /* NetworkReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58D1B122C150D700405315 /* NetworkReader.swift */; };
9A58D1B422C179B200405315 /* NetworkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A58D1B322C179B200405315 /* NetworkView.swift */; };
9A5B1CBF229E78F0008B9D3C /* Observable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5B1CBE229E78F0008B9D3C /* Observable.swift */; };
9A5B1CC5229E7B40008B9D3C /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5B1CC4229E7B40008B9D3C /* Extensions.swift */; };
9A6CFC0122A1C9F5001E782D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9A6CFC0022A1C9F5001E782D /* Assets.xcassets */; };
Expand Down Expand Up @@ -55,9 +60,14 @@
9A1410FF229E721200D29793 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
9A141101229E721200D29793 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9A141102229E721200D29793 /* Stats.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Stats.entitlements; sourceTree = "<group>"; };
9A426DB722C2B5EE00C064C4 /* macAppUpdater.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = macAppUpdater.swift; sourceTree = "<group>"; };
9A426DBD22C2BE0000C064C4 /* Updates.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Updates.storyboard; sourceTree = "<group>"; };
9A57A18422A1D26D0033E318 /* MenuBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuBar.swift; sourceTree = "<group>"; };
9A57A19A22A1E1C50033E318 /* Module.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Module.swift; sourceTree = "<group>"; };
9A57A19C22A1E3270033E318 /* CPU.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CPU.swift; sourceTree = "<group>"; };
9A58D1AF22C150C800405315 /* Network.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Network.swift; sourceTree = "<group>"; };
9A58D1B122C150D700405315 /* NetworkReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkReader.swift; sourceTree = "<group>"; };
9A58D1B322C179B200405315 /* NetworkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkView.swift; sourceTree = "<group>"; };
9A5B1CBE229E78F0008B9D3C /* Observable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Observable.swift; sourceTree = "<group>"; };
9A5B1CC4229E7B40008B9D3C /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
9A6CFC0022A1C9F5001E782D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
Expand Down Expand Up @@ -138,12 +148,22 @@
path = Stats;
sourceTree = "<group>";
};
9A58D1AE22C150B800405315 /* Network */ = {
isa = PBXGroup;
children = (
9A58D1AF22C150C800405315 /* Network.swift */,
9A58D1B122C150D700405315 /* NetworkReader.swift */,
);
path = Network;
sourceTree = "<group>";
};
9A5B1CB3229E72A7008B9D3C /* Supporting Files */ = {
isa = PBXGroup;
children = (
9A6CFC0022A1C9F5001E782D /* Assets.xcassets */,
9AFFCB3A22B3FD0500B0E6D8 /* About.storyboard */,
9A1410FE229E721200D29793 /* Main.storyboard */,
9AFFCB3A22B3FD0500B0E6D8 /* About.storyboard */,
9A426DBD22C2BE0000C064C4 /* Updates.storyboard */,
9A141101229E721200D29793 /* Info.plist */,
9A141102229E721200D29793 /* Stats.entitlements */,
);
Expand All @@ -153,10 +173,11 @@
9A5B1CBA229E7892008B9D3C /* Modules */ = {
isa = PBXGroup;
children = (
9A09C89C22B3A7BB0018426F /* Battery */,
9A7B8F5C22A2926500DEB352 /* CPU */,
9A7B8F6222A2C17000DEB352 /* Memory */,
9A7B8F6322A2C17500DEB352 /* Disk */,
9A09C89C22B3A7BB0018426F /* Battery */,
9A58D1AE22C150B800405315 /* Network */,
);
path = Modules;
sourceTree = "<group>";
Expand All @@ -167,6 +188,7 @@
9A5B1CBE229E78F0008B9D3C /* Observable.swift */,
9A57A19A22A1E1C50033E318 /* Module.swift */,
9A5B1CC4229E7B40008B9D3C /* Extensions.swift */,
9A426DB722C2B5EE00C064C4 /* macAppUpdater.swift */,
);
path = libs;
sourceTree = "<group>";
Expand All @@ -177,6 +199,7 @@
9A09C8A122B3D94D0018426F /* BatteryView.swift */,
9A74D59322B4315C004FE1FA /* Chart.swift */,
9A74D59622B44498004FE1FA /* Mini.swift */,
9A58D1B322C179B200405315 /* NetworkView.swift */,
);
path = Widgets;
sourceTree = "<group>";
Expand Down Expand Up @@ -279,6 +302,11 @@
TargetAttributes = {
9A1410F4229E721100D29793 = {
CreatedOnToolsVersion = 10.2.1;
SystemCapabilities = {
com.apple.Sandbox = {
enabled = 1;
};
};
};
9AFA401D22AE49A100FE90BC = {
CreatedOnToolsVersion = 10.2.1;
Expand Down Expand Up @@ -312,6 +340,7 @@
9A6CFC0122A1C9F5001E782D /* Assets.xcassets in Resources */,
9AFFCB3B22B3FD0500B0E6D8 /* About.storyboard in Resources */,
9A141100229E721200D29793 /* Main.storyboard in Resources */,
9A426DBE22C2BE0000C064C4 /* Updates.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -332,15 +361,19 @@
buildActionMask = 2147483647;
files = (
9A09C8A222B3D94D0018426F /* BatteryView.swift in Sources */,
9A426DB822C2B5EE00C064C4 /* macAppUpdater.swift in Sources */,
9A7B8F6F22A2C57000DEB352 /* DiskReader.swift in Sources */,
9A7B8F6922A2C3A100DEB352 /* Memory.swift in Sources */,
9A7B8F5E22A2A57600DEB352 /* CPUReader.swift in Sources */,
9A74D59422B4315C004FE1FA /* Chart.swift in Sources */,
9A58D1B422C179B200405315 /* NetworkView.swift in Sources */,
9A09C89E22B3A7C90018426F /* Battery.swift in Sources */,
9A7B8F6D22A2C3D600DEB352 /* MemoryReader.swift in Sources */,
9A57A18522A1D26D0033E318 /* MenuBar.swift in Sources */,
9A57A19D22A1E3270033E318 /* CPU.swift in Sources */,
9A58D1B222C150D700405315 /* NetworkReader.swift in Sources */,
9A09C8A022B3A7E20018426F /* BatteryReader.swift in Sources */,
9A58D1B022C150C800405315 /* Network.swift in Sources */,
9A57A19B22A1E1C50033E318 /* Module.swift in Sources */,
9A5B1CBF229E78F0008B9D3C /* Observable.swift in Sources */,
9A7B8F6B22A2C3A700DEB352 /* Disk.swift in Sources */,
Expand Down Expand Up @@ -505,6 +538,10 @@
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = RP2S87B72W;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
);
INFOPLIST_FILE = "$(SRCROOT)/Stats/Supporting Files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -528,6 +565,10 @@
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = RP2S87B72W;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)",
);
INFOPLIST_FILE = "$(SRCROOT)/Stats/Supporting Files/Info.plist";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
Expand Down
71 changes: 70 additions & 1 deletion Stats/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ extension Notification.Name {
static let killLauncher = Notification.Name("killLauncher")
}

let modules: Observable<[Module]> = Observable([CPU(), Memory(), Disk(), Battery()])
let modules: Observable<[Module]> = Observable([CPU(), Memory(), Disk(), Battery(), Network()])
let colors: Observable<Bool> = Observable(true)

@NSApplicationMain
Expand Down Expand Up @@ -81,3 +81,72 @@ class AboutVC: NSViewController {
}
}
}

class UpdatesVC: NSViewController {
@IBOutlet weak var mainView: NSStackView!
@IBOutlet weak var spinnerView: NSView!
@IBOutlet weak var noInternetView: NSView!
@IBOutlet weak var mainTextLabel: NSTextFieldCell!
@IBOutlet weak var currentVersionLabel: NSTextField!
@IBOutlet weak var latestVersionLabel: NSTextField!
@IBOutlet weak var downloadButton: NSButton!
@IBOutlet weak var spinner: NSProgressIndicator!

let updater = macAppUpdater(user: "exelban", repo: "stats")
var url: String?

override func viewDidLoad() {
super.viewDidLoad()
self.view.wantsLayer = true

self.spinner.startAnimation(self)

updater.check() { result, error in
if error != nil && error as! String == "No internet connection" {
DispatchQueue.main.async(execute: {
self.spinnerView.isHidden = true
self.noInternetView.isHidden = false
})
return
}

guard error == nil, let version: version = result else {
print("Error: \(error ?? "check error")")
return
}

DispatchQueue.main.async(execute: {
self.spinner.stopAnimation(self)
self.spinnerView.isHidden = true
self.mainView.isHidden = false
self.currentVersionLabel.stringValue = version.current
self.latestVersionLabel.stringValue = version.latest
self.url = version.url

if !version.newest {
self.mainTextLabel.stringValue = "No new version available"
self.downloadButton.isEnabled = false
}
})
}
}

override func awakeFromNib() {
if self.view.layer != nil {
self.view.window?.backgroundColor = .white
self.view.layer?.backgroundColor = .white
}
}

@IBAction func download(_ sender: Any) {
guard let urlString = self.url, let url = URL(string: urlString) else {
return
}
NSWorkspace.shared.open(url)
self.view.window?.close()
}

@IBAction func exit(_ sender: Any) {
self.view.window?.close()
}
}
18 changes: 16 additions & 2 deletions Stats/MenuBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
import Cocoa
import ServiceManagement

let MODULE_HEIGHT = CGFloat(NSApplication.shared.mainMenu?.menuBarHeight ?? 22)
let MODULE_WIDTH = CGFloat(32)
let MODULE_HEIGHT: CGFloat = NSApplication.shared.mainMenu?.menuBarHeight ?? 22
let MODULE_WIDTH: CGFloat = 32
let MODULE_MARGIN: CGFloat = 2

class MenuBar {
let defaults = UserDefaults.standard
Expand Down Expand Up @@ -73,14 +74,27 @@ class MenuBar {
menu.addItem(preferences)

menu.addItem(NSMenuItem.separator())

let updateMenu = NSMenuItem(title: "Check for updates", action: #selector(checkUpdate), keyEquivalent: "")
updateMenu.target = self

let aboutMenu = NSMenuItem(title: "About Stats", action: #selector(openAbout), keyEquivalent: "")
aboutMenu.target = self

menu.addItem(updateMenu)
menu.addItem(aboutMenu)
menu.addItem(NSMenuItem(title: "Quit Stats", action: #selector(NSApplication.terminate(_:)), keyEquivalent: ""))

return menu
}

@objc func checkUpdate(_ sender : NSMenuItem) {
let updatesVC: NSWindowController? = NSStoryboard(name: "Updates", bundle: nil).instantiateController(withIdentifier: "UpdatesVC") as? NSWindowController
updatesVC?.window?.center()
updatesVC?.window?.level = .floating
updatesVC!.showWindow(self)
}

@objc func openAbout(_ sender : NSMenuItem) {
let aboutVC: NSWindowController? = NSStoryboard(name: "About", bundle: nil).instantiateController(withIdentifier: "AboutVC") as? NSWindowController
aboutVC?.window?.center()
Expand Down
4 changes: 2 additions & 2 deletions Stats/Modules/Battery/BatteryReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import IOKit.ps

class BatteryReader: Reader {
var usage: Observable<Float>!
var usage: Observable<Double>!
var available: Bool = false
var updateTimer: Timer!

Expand Down Expand Up @@ -49,7 +49,7 @@ class BatteryReader: Reader {
cap = 0 - cap
}

self.usage << Float(cap)
self.usage << Double(cap)
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion Stats/Modules/CPU/CPU.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ class CPU: Module {
sender.state = sender.state == NSControl.StateValue.on ? NSControl.StateValue.off : NSControl.StateValue.on
self.defaults.set(widgetCode, forKey: "\(name)_widget")
self.widgetType = widgetCode
self.initWidget()
self.active << false
initWidget()
self.active << true
}
}
4 changes: 2 additions & 2 deletions Stats/Modules/CPU/CPUReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

class CPUReader: Reader {
var usage: Observable<Float>!
var usage: Observable<Double>!
var available: Bool = true
var cpuInfo: processor_info_array_t!
var prevCpuInfo: processor_info_array_t?
Expand Down Expand Up @@ -77,7 +77,7 @@ class CPUReader: Reader {
inUseOnAllCores = inUseOnAllCores + inUse
totalOnAllCores = totalOnAllCores + total
}
self.usage << (Float(inUseOnAllCores) / Float(totalOnAllCores))
self.usage << (Double(inUseOnAllCores) / Double(totalOnAllCores))

CPUUsageLock.unlock()

Expand Down
4 changes: 2 additions & 2 deletions Stats/Modules/Disk/DiskReader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation

class DiskReader: Reader {
var usage: Observable<Float>!
var usage: Observable<Double>!
var available: Bool = true
var updateTimer: Timer!

Expand Down Expand Up @@ -38,7 +38,7 @@ class DiskReader: Reader {
let free = freeDiskSpaceInBytes()
let usedSpace = total - free

self.usage << (Float(usedSpace) / Float(total))
self.usage << (Double(usedSpace) / Double(total))
}

func totalDiskSpaceInBytes() -> Int64 {
Expand Down
Loading

0 comments on commit 613568d

Please sign in to comment.