Friday 19 April 2024

Adding repo name to bash prompt string

Overriding the custom prompt

To overwrite the default bash prompt string, also known as PS1(prompt string one), create a file name at ~/.config/git/git-prompt.sh

e.g. C:/Users/ItsMe/.config/git/git-prompt.sh

You'll need to set a variable named PS1. Here's a very simple example of a custom prompt of "hello" followed by a newline and the classic '$' symbol:

PS1="hello\n$ "



Thursday 30 March 2023

Uploading to dropbox using the sdk

I used to move my files into a dropbox enabled folder and let them deal with the uploading but that feature has become so unreliable to be uesless to me. Instead I've written this python3 script to upload files using the dropbox sdk instead.

Downloading the dropbox python sdk is as easy as:

 pip install dropbox

 If your file is less than 150MB then dropbox.files_upload can be used, larger than that and dropbox.files_upload_session_start must be called and given a small chunk of your file, with the remaining chunks being uploaded with dropbox.files_upload_session_append and the final chunk with  dropbox.files_upload_session_finish.  

What a faff! So this script will do it all for you and print out a nice progress bar too :) 

 
This has been sped up a lot

Call with upload_to_dropbox(file_path, target_path) where file_path is the file you want to upload and target_path is the dropbox location (including the uploaded file name).
It will also return a True value if the upload was successful.

I work out the dropbox location by finding the folder I want in a browser and getting the url
e.g. "https://www.dropbox.com/home/Projects/Groobles%20Files"
Then remove the dropbox.com/home bit and replace %20s with the spaces they represent, then add the file name
e.g. "/Projects/Groobles Files/uploadedfile.zip"

The script:

import os
import math
import dropbox

## Token required to access dropbox
ACCESS_TOKEN="ABCDEFGHIJKLMNOP1234567890SECRETTOKEN0000"

class UploadProgressBar:    
    def __init__(self, file_size, bar_length=20):
        self.file_size = file_size
        self.bar_length = bar_length
        self.progress = 0
        guide_bar_string=" "
        for _ in range(bar_length):
            guide_bar_string+="_"
        print(guide_bar_string)
        print("|", end="")#start of progress bar
    def updateProgress(self, uploaded_data):
        """! Update the bars progress level.
        @param uploaded_data int - The amount of data uploaded, this will be compared to the self.file_size. (Using file.tell() can be used to collect this information)
        @note Printing anything before the progress bar is finished will ruin the look of the progress bar design
        """
        percentage = (uploaded_data / self.file_size) * self.bar_length
        new_progress = math.floor(percentage)
        
        if (new_progress > self.progress):
            newbars=""
            for _ in range(new_progress - self.progress):
                newbars += "#"
            self.progress = new_progress
            if (self.progress == self.bar_length):
                print(newbars + "|")#end of the progress bar
            else:
                print(newbars, end="", flush=True)
        

def upload_file(file_path,target_path):
    dbx = dropbox.Dropbox(ACCESS_TOKEN, timeout=900)
    with open(file_path, "rb") as f:
        file_size = os.path.getsize(file_path)
        chunk_size = 4 * 1024 * 1024
        if file_size <= chunk_size:
            print("File is smaller than 150MB, uploading to dropbox using the small file method...")
            try:
                result = dbx.files_upload(f.read(), target_path, mode=dropbox.files.WriteMode.overwrite)
            except dropbox.exceptions.ApiError as err:
                print("\nError:", err)
                return False
            else:
                print(result.name , "uploaded successfully to ", result.path_display)
                return True
        else:
            print("File is larger than 150MB, uploading to dropbox using large file method...")
            try:
                print("Starting upload session...")
                progbar = UploadProgressBar(os.path.getsize(file_path), 20);
                progbar.updateProgress(0);
                upload_session_start_result = dbx.files_upload_session_start(f.read(chunk_size))
                cursor = dropbox.files.UploadSessionCursor(session_id=upload_session_start_result.session_id,offset=f.tell())
                commit = dropbox.files.CommitInfo(path=target_path, mode=dropbox.files.WriteMode.overwrite)
                while f.tell() < file_size:
                    if (file_size - f.tell()) <= chunk_size:
                        result = dbx.files_upload_session_finish(f.read(chunk_size), cursor, commit)
                        progbar.updateProgress(os.path.getsize(file_path))
                    else:
                        progbar.updateProgress(f.tell())
                        dbx.files_upload_session_append(f.read(chunk_size), cursor.session_id, cursor.offset)
                        cursor.offset = f.tell()
            except dropbox.exceptions.ApiError as err:
                print("\nError:", err)
                return False
            else:
                print(result.name , "uploaded successfully to", result.path_display)
                return True
    return False #we shouldn't reach here but we might if there's an issue on dropbox's end




Monday 10 January 2022

How to manually link IPP libraries

 IPP or oneAPI installs a visual studio extension that does all this linking for you, but if you are using a version of visual studio that is no longer supported, or if the extension just isn't installing for you for some reason (like I found...) then here's how to static link it manually.

You may need to add additional libraries for your needs but this is the gist of it:

Wednesday 20 October 2021

How to set up an automatic "good morning" slack messenger

 My boss wants us to greet the team every morning but I'm a busy woman so here's how I automated a "good morning" message to slack every day from my PC.

  • Step 1: Generate a user token

We need a user token to authorise messages send to the slack API, these are tokens that start with "xoxp". If you don't already have one, we'll have to create a slack app, install it to our slack workspace, and give it "user:chat" permissions to generate a token.
    1. Go to https://api.slack.com/apps/ to create a new app. It will need to be made on the same workspace you're "good morning" messages will be posted to
    2. In your new app, go to "App Manifest" in the settings menu on the left then click "Edit"
    3. In the manifest add a "user" to the oauth_config scopes and give it "char:write" permissions e.g.:
      oauth_config:
        scopes:
          user:
            - chat:write
    4. Now go to "OAuth & Permissions" in the settings menu and we should now have a User OAuth Token. 
    5. Install/reinstall your app to the workspace. There should be a prompt asking you to do so (You'll need to do that every time you make any change to the app)

You'll need to provide these arguments:
- token (your user token)
- channel (the channel to post the message)
- as_user (set to true)

There are multiple ways to do this, check out the API link above for more info. But I'm going to use a batch script and http for simplicity.

I've also randomised my message slightly for variety.

set min=1
set max=3
set /a selectionNum=(%RANDOM%*max/32768)+min

if %selectionNum%==1 (
set message=good morning
goto sendmsg
)
if %selectionNum%==2 (
set message=good morning :slightly_smiling_face:
goto sendmsg
)
if %selectionNum%==3 (
set message=morning!
goto sendmsg
)

:sendmsg
curl -d "text=%message%" -d "channel=general" -d "as_user=true" -H "Authorization: Bearer xoxp-xxxxxx-xxxxxx-xxxxxx-xxxxxx" -X POST https://slack.com/api/chat.postMessage

  • Step 3: Trigger your script in the morning
On Linux or Mac you can set up a cron job, I'm on Windows so I'm going to use the Task Scheduler.
  1. Open Windows Task Scheduler and create a new task
  2. Add a name as description
  3. Click the "Triggers" tag and set the job to run every day at whatever time (chose an slightly off time like 9:08 so the messages look more natural. I've set mine to 9:17 because everyone knows I'm not an early bird)
  4. Click the "Actions" tab and add the path to your script
  5. Save your task
  • Step 4: Carry on with your life!
Your script will be social for you. As long as your computer is on the script will be able to send the message.




Wednesday 17 February 2021

"Could not perform submodule update" after jenkins git update

 

This is the error I'm getting after updating the git version on my jenkins server:


 > git.exe config --get submodule.module.url # timeout=10
hudson.plugins.git.GitException: Command "git.exe config --get submodule.my-module.url" returned status code 1:
...
Caused: java.io.IOException: Could not perform submodule update
...
Finished: FAILURE



My solution was opening the .gitmodules file (a hidden file, found in the repo root) and adding "'.git" to the end of the url.

e.g.:
[submodule "my-module"]
path = my-module
url = git@bitbucket.org:name/my-module.git

Friday 31 January 2020

pkgbuild basics - Creating a basic pkg installer on OSX


pkguild is a command-line tool used to create installers, there are easier tools for creating installers such as Packages which uses a graphical user interface.

The way pkgbuild works is that you create a folder structure that acts as the root directory of the target machine, then you move the files for the installer into this fake root folder with the desired folder structure. 
When you run the pkgbuild command you tell it what the root folder is and pkbuild essentially trims off that part of the file path to figure out where to install your files.
The result will be an installer (.pkg file) that will install your files and look something like this:
Image of an installer dialog for example project myapp

In this example I've created a directory called "instroot" in my documents. 
I want "myApp" to be installed at /Applications/myApp so I've copied it to the new folder:
~/Documents/instroot/Applications/MyApp

I also want some text files to be installed at /Library/Application Support/myApp so I've copied them into the new folder too:
~/Documents/instroot/Library/Application Support/myApp/myAppFile1.txt





once all the files for the installer are in the correct place, we just need to call this command:

pkgbuild --root --identifier --version packagename

root: the install root
identifier: an ID for your installer (used only by the operating system and can be anything you want but so try to make it meaningful and unique)
version: the version of your project
packagename: the name for the output installer, the name is also used in the installer dialog

for my example project the command is:

pkgbuild --root ~/Documents/instroot --identifier com.myapp.test --version 1.0 myapp.pkg


We can also use the pkgutil --payload-files command to list the installer files and sanity check the contents.

Now we have an installer called myapp.pkg! Double clicking it will start the installer.





Friday 19 July 2019

Chuck DirectSound error fix


I'm learning dsp and following a tutorial that uses chuck, I install it, try it, and it falls over instantly with this error:

[chuck]: (DirectSound) error (Generic error) creating input buffer (Default Device)!



Solution:
  1. Go to Start Settings Privacy Settings → Microphone
  2. Turn on "Allow apps to access your microphone"
Now you'll never see this error again!

Microphone settings window shows "Allow apps to access your microphone" turned on.

Adding repo name to bash prompt string

Overriding the custom prompt To overwrite the default bash prompt string, also known as PS1(prompt string one), create a file name at ~/.con...