Skip to content

Instantly share code, notes, and snippets.

@shekibobo
shekibobo / README.md
Last active May 26, 2023 14:03
organize_astro_data.rb

Organize Astrophotography Data

This is a Ruby script to help organize astrophotography data into folders using keywords that can then be used to help process in PixInsight using WeightedBatchPreProcessing.

This version of the script was written to organize or reorganize the data collected to match my current workflow, which I will outline below.

Camera

I currently use a Canon EOS 1500 (T7) DSLR for astrophotography, and attach it to one of my telescopes. Data capture is performed using the ASIAir Plus. In the ASIAir app, my camera's settings are configured to include ISO, Date, and Temp in the customized file name.

@shekibobo
shekibobo / ParcelTesting.kt
Created March 8, 2021 22:36
Testing a Parcelable class implemented with @parcelize
inline fun <reified T> T.forceParcel(): T? where T : Parcelable {
val bytes = Parcel.obtain().use {
writeParcelable(this@forceParcel, 0)
marshall()
}
return Parcel.obtain().use {
unmarshall(bytes, 0, bytes.size)
setDataPosition(0)
readParcelable(T::class.java.classLoader)
}
@shekibobo
shekibobo / README.md
Last active March 2, 2020 11:04
Android: Base Styles for Button (not provided by AppCompat)

How to create custom button styles using Android's AppCompat-v7:21

Introduction

AppCompat is an Android support library to provide backwards-compatible functionality for Material design patterns. It currently comes bundled with a set of styles in the Theme.AppCompat and Widget.AppCompat namespaces. However, there is a critical component missing which I would have thought essential to provide the a default from which we could inherit our styles: Widget.AppCompat.Button. Sure, there's Widget.AppCompat.Light.ActionButton, but that doesn't actually inherit from Widget.ActionButton, which does not inherit from Widget.Button, so we might get some unexpected behavior using that as our base button style, mainly because Widget.ActionButton strictly belongs in the ActionBar.

So, if we want to have a decently normal default button style related to AppCompat, we need to make it ourselves. Let's start by digging into the Android SDK to see how it's doing default styles.

Digging In

@shekibobo
shekibobo / StringFormatDetectorTest.kt
Last active August 27, 2019 17:06
Sample test of StringFormatDetector against equivalent Java and Kotlin classes
import com.android.tools.lint.checks.StringFormatDetector
import com.android.tools.lint.checks.infrastructure.LintDetectorTest
import com.android.tools.lint.detector.api.Detector
import com.android.tools.lint.detector.api.Issue
class StringFormatDetectorTest : LintDetectorTest() {
override fun getDetector(): Detector = StringFormatDetector()
override fun getIssues(): MutableList<Issue> = mutableListOf(
StringFormatDetector.ARG_COUNT,
@shekibobo
shekibobo / InjectableActivityScenario.kt
Created July 27, 2019 01:50 — forked from rharter/InjectableActivityScenario.kt
An ActivityScenario that allows you to use Dagger Android's automatic, lifecycle based injection without making your Application class `open`, or overriding it in tests.
package com.pixite.pigment.testing
import android.app.Activity
import android.app.Instrumentation
import android.content.Context
import android.content.Intent
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
@shekibobo
shekibobo / InjectableActivityScenario.kt
Created July 27, 2019 01:50 — forked from rharter/InjectableActivityScenario.kt
An ActivityScenario that allows you to use Dagger Android's automatic, lifecycle based injection without making your Application class `open`, or overriding it in tests.
package com.pixite.pigment.testing
import android.app.Activity
import android.app.Instrumentation
import android.content.Context
import android.content.Intent
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
@shekibobo
shekibobo / loadProperties.gradle
Created April 22, 2019 15:18
Load properties from a given file within the project.
def propertiesFrom(filename) {
def properties = new Properties()
def file = rootProject.file(filename)
if (file.exists()) {
properties.load(new FileInputStream(file))
} else {
System.out.println("[WARNING] Properties file ${filename} not found. Returning empty properties.")
}
return properties
}
@shekibobo
shekibobo / signingconfigs.gradle
Last active April 22, 2019 15:22
Load signing configs from secret keystore file for gradle build.
signingConfigs {
debug {
storeFile rootProject.file("signing/debug.keystore")
storePassword "android"
keyAlias "androiddebugkey"
keyPassword "android"
}
release {
def keystoreProperties = propertiesFrom("signing/keystore.properties")
@shekibobo
shekibobo / assembleDistribution.gradle
Created April 22, 2019 15:20
Assemble all distribution apks with filenames and copy the debug and release versions of each build flavor to an `apks` directory.
task copyApks(type: Copy) {
["debug", "release"].each { type ->
from "build/outputs/apk/${type}/"
}
into "apks/all-${AppVersion.fullVersionCode}-${gitSha}"
include '**/*.apk'
rename { String filename ->
filename.replace("app-", "").replace(".apk", "-${AppVersion.fullVersionCode}-${gitSha}.apk")
}
}
@shekibobo
shekibobo / ViewGroupExt.kt
Last active April 22, 2019 15:14
Fill a ViewGroup with items using a given layout. Easy to replace, reuses child views if possible.
/**
Copyright 2019 Joshua Kovach
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software