Skip to content

Commit

Permalink
[Project] I did way too much
Browse files Browse the repository at this point in the history
  • Loading branch information
kirb committed Jun 23, 2022
1 parent a2cd835 commit 9d60056
Show file tree
Hide file tree
Showing 35 changed files with 930 additions and 702 deletions.
22 changes: 11 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ export ARCHS = arm64
endif

ifeq ($(ALPHA), 1)
PRODUCT_BUNDLE_IDENTIFIER = xyz.willy.Zebralpha
export APP_NAME = "Zebra-Alpha"
PRODUCT_BUNDLE_IDENTIFIER = com.getzbra.zebra2
export APP_NAME = "Zebra"
export LIBEXEC_FOLDER = zebralpha
else ifeq ($(BETA), 1)
PRODUCT_BUNDLE_IDENTIFIER = xyz.willy.Zebeta
PRODUCT_BUNDLE_IDENTIFIER = com.getzbra.zebra2
export APP_NAME = "Zebra-Beta"
export LIBEXEC_FOLDER = zebeta
else
PRODUCT_BUNDLE_IDENTIFIER = xyz.willy.Zebra
PRODUCT_BUNDLE_IDENTIFIER = com.getzbra.zebra2
export APP_NAME = "Zebra"
export LIBEXEC_FOLDER = zebra
endif
Expand All @@ -44,13 +44,13 @@ _THEOS_PACKAGE_DEFAULT_VERSION_FORMAT = $(THEOS_PACKAGE_BASE_VERSION)$(VERSION.E

SUBPROJECTS = Supersling #Relaunch

ifeq ($(ALPHA), 1)
before-package::
sed -Ei '' 's/^Name: Zebra/Name: Zebra [ALPHA]/g;s/^Package: (.*)$/Package: \1alpha/g' $(THEOS_STAGING_DIR)/DEBIAN/control
else ifeq ($(BETA), 1)
before-package::
sed -Ei '' 's/^Name: Zebra/Name: Zebra [BETA]/g;s/^Package: (.*)$/Package: \1beta/g' $(THEOS_STAGING_DIR)/DEBIAN/control
endif
# ifeq ($(ALPHA), 1)
# before-package::
# sed -Ei '' 's/^Name: Zebra/Name: Zebra [ALPHA]/g;s/^Package: (.*)$/Package: \1alpha/g' $(THEOS_STAGING_DIR)/DEBIAN/control
# else ifeq ($(BETA), 1)
# before-package::
# sed -Ei '' 's/^Name: Zebra/Name: Zebra [BETA]/g;s/^Package: (.*)$/Package: \1beta/g' $(THEOS_STAGING_DIR)/DEBIAN/control
# endif

after-stage::
chmod 6755 $(THEOS_STAGING_DIR)/usr/libexec/$(LIBEXEC_FOLDER)/supersling
Expand Down
2 changes: 1 addition & 1 deletion Vendor/Plains
28 changes: 18 additions & 10 deletions Zebra.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

82 changes: 48 additions & 34 deletions Zebra/Controllers/HTTP/HTTPRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@

import Foundation

enum HTTPError: Error {
enum HTTPError: Error, LocalizedError {
case general(error: Error)
case statusCode(statusCode: Int, response: HTTPURLResponse)
case cancelled
case badResponse
case statusCode(statusCode: Int, response: HTTPURLResponse)

var response: HTTPURLResponse? {
switch self {
case .general(_), .badResponse:
case .general(_), .cancelled, .badResponse:
return nil
case .statusCode(_, let response):
return response
Expand All @@ -36,6 +37,12 @@ enum HTTPError: Error {
case .general(let error):
return error.localizedDescription

case .cancelled:
return .localize("The request was cancelled.")

case .badResponse:
return .localize("The server returned an unexpected response.")

case .statusCode(let statusCode, _):
switch statusCode {
case 401, 403:
Expand All @@ -47,53 +54,54 @@ enum HTTPError: Error {
default:
return "\(String.localize("The server returned an unexpected error.")) (\(statusCodeString))"
}

case .badResponse:
return .localize("The server returned an unexpected response.")
}
}
}

class HTTPRequest {
struct Response<T> {
let statusCode: Int
let data: T?
let response: HTTPURLResponse?
let error: Error?
}

struct Response<T> {
let statusCode: Int
let data: T?
let response: HTTPURLResponse?
let error: Error?
}
extension URLSession {

static func data(session: URLSession = .shared, for request: URLRequest) async throws -> (data: Data, response: HTTPURLResponse) {
return try await withCheckedThrowingContinuation { result in
let task = URLSession.shared.dataTask(with: request) { data, response, error in
do {
func data(with request: URLRequest) async throws -> (data: Data, response: HTTPURLResponse) {
var task: URLSessionTask!

return try await withTaskCancellationHandler { [task] in
task?.cancel()
} operation: {
try await withCheckedThrowingContinuation { result in
task = dataTask(with: request) { data, response, error in
if let error = self.error(for: response, error: error, forAsync: true) {
throw error
}
guard let data = data,
let response = response as? HTTPURLResponse else {
throw NSError(domain: NSURLErrorDomain, code: NSURLErrorBadServerResponse)
result.resume(throwing: HTTPError.general(error: error))
} else {
guard let response = response as? HTTPURLResponse else {
result.resume(throwing: HTTPError.badResponse)
return
}
result.resume(returning: (data!, response))
}
result.resume(returning: (data, response))
} catch {
result.resume(throwing: error)
}
task.resume()
}
task.resume()
}
}

static func json<T: Codable>(session: URLSession = .shared, for request: URLRequest) async throws -> T {
let (data, _) = try await data(session: session, for: request)
return try JSONDecoder().decode(T.self, from: data)
func json<T: Codable>(with request: URLRequest, type: T.Type = T.self, decoder: JSONDecoder = .init()) async throws -> T {
let (data, _) = try await self.data(with: request)
return try decoder.decode(T.self, from: data)
}

static func download(session: URLSession = .shared, for request: URLRequest, completion: @escaping (Response<URL>) -> Void) {
let task = session.downloadTask(with: request) { url, response, error in
func download(with request: URLRequest, completion: @escaping (Response<URL>) -> Void) {
let task = downloadTask(with: request) { url, response, error in
if let error = self.error(for: response, error: error) {
completion(Response(statusCode: 0, data: nil, response: nil, error: error))
return
}

guard let url = url,
let response = response as? HTTPURLResponse else {
completion(Response(statusCode: 0, data: url, response: nil, error: HTTPError.badResponse))
Expand All @@ -104,9 +112,15 @@ class HTTPRequest {
task.resume()
}

private static func error(for response: URLResponse?, error: Error?, forAsync: Bool = false) -> Error? {
if let error = error {
return HTTPError.general(error: error)
private func error(for response: URLResponse?, error: Error?, forAsync: Bool = false) -> Error? {
if let error = error as? NSError {
switch (error.domain, error.code) {
case (NSURLErrorDomain, NSURLErrorCancelled):
return HTTPError.cancelled

default:
return HTTPError.general(error: error)
}
}

guard let response = response as? HTTPURLResponse else {
Expand Down
51 changes: 51 additions & 0 deletions Zebra/Controllers/Plains/JobQueue.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// JobQueue.swift
// Zebra
//
// Created by Adam Demasi on 19/6/2022.
// Copyright © 2022 Zebra Team. All rights reserved.
//

import Foundation

class JobQueue<Job: Hashable> {

typealias QueueProcessor = (Job) -> Void

let queue: DispatchQueue
let taskLimit: Int
let queueProcessor: QueueProcessor

private(set) var pendingJobs = [Job]()
private(set) var runningJobs = [Job]()

init(queue: DispatchQueue, taskLimit: Int, queueProcessor: @escaping QueueProcessor) {
self.queue = queue
self.taskLimit = taskLimit
self.queueProcessor = queueProcessor
}

private func tick() {
queue.async {
if !self.pendingJobs.isEmpty && self.runningJobs.count < self.taskLimit {
let job = self.pendingJobs.removeFirst()
self.runningJobs.append(job)
self.queueProcessor(job)
self.tick()
}
}
}

func enqueue(job: Job) {
pendingJobs.append(job)
tick()
}

func complete(job: Job) {
if let index = runningJobs.firstIndex(of: job) {
runningJobs.remove(at: index)
}
tick()
}

}
36 changes: 26 additions & 10 deletions Zebra/Controllers/Plains/Source Files/SourceFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ import UniformTypeIdentifiers
enum SourceFileKind {
case any, text, deb, gzip, bzip2, lzma, xz, zstd

init?(aptCompressorName: String) {
switch aptCompressorName {
case "gz": self = .gzip
case "bz2": self = .bzip2
case "lzma": self = .lzma
case "xz": self = .xz
case "zst": self = .zstd
default: return nil
}
}

var type: UTType {
switch self {
case .any: return .data
Expand Down Expand Up @@ -65,21 +76,24 @@ enum SourceFileKind {
enum SourceFile {
case inRelease, release, releaseGpg
case packages(kind: SourceFileKind)
case paymentEndpoint

var kind: SourceFileKind {
switch self {
case .inRelease: return .any
case .release: return .text
case .releaseGpg: return .any
case .inRelease: return .any
case .release: return .text
case .releaseGpg: return .any
case .packages(let kind): return kind
case .paymentEndpoint: return .any
}
}

var name: String {
switch self {
case .inRelease: return "InRelease"
case .release: return "Release"
case .releaseGpg: return "Release.gpg"
case .inRelease: return "InRelease"
case .release: return "Release"
case .releaseGpg: return "Release.gpg"
case .paymentEndpoint: return "payment_endpoint"
case .packages(let kind):
if let ext = kind.extension {
return "Packages.\(ext)"
Expand All @@ -91,13 +105,15 @@ enum SourceFile {
var progressWeight: Int64 {
switch self {
// Either InRelease or Release + Release.gpg.
case .inRelease: return 100
case .inRelease: return 100

// 80 + 20 = 100
case .release: return 80
case .releaseGpg: return 20
case .release: return 80
case .releaseGpg: return 20

case .paymentEndpoint: return 20

// The remainder is the Packages file.
// The majority of the time will be spent on Packages.
case .packages(_): return 800
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension SourceRefreshController {
}
self.backgroundTask = task

self.refresh()
self.refresh(priority: .background)
}
}

Expand All @@ -47,6 +47,7 @@ extension SourceRefreshController {
internal func completeBackgroundRefresh() {
// If we were launched from a background task, we need to tell the OS we’ve finished.
backgroundTask?.setTaskCompleted(success: true)
backgroundTask = nil
}

}
Loading

0 comments on commit 9d60056

Please sign in to comment.