Sunday, May 29, 2022

Airbnb Guest Checklist

 When you search for a room to rent for a day or a bit longer, you may be quite surprised when you see the place, or what you pay for it, if you don't check the following items.  These are just from my experience.  

  • The price per night that you see on the list of rentals when you search on the Airbnb portal doesn't include the fees.  These, especially for 1-2 nights start can increase your cost even by 50% from my experience.  For any rental, you consider renting, open the rental details and check for fees.  Some are fees paid by the owner to Airbnb, other fees are for cleaning etc.  Esp. the latter ones differ a lot along rentals. 
  • When you are looking for a room with a private bathroom, make sure to check what the owner considers "private".  You may be thinking of a bathroom with an entrance from your room.  But sometimes owners advertise as "private" bathrooms with an entrance from a shared hall as long as you're the only one allowed to use it. Contact the owner and confirm.  Don't assume.
  • Quite often, the guest unit that you're renting isn't on the ground floor or in general accessible only via stairs.  Make sure you're comfortable with the stairs you will be using every time to get to your room or to get out of it.  For example, are you comfortable if they're outside spiral stairs? 
  • If you rent a room in a shared hall, you may want to check that you'll be able to lock the room from outside, once you check in and decide to go out for dinner or just for a walk.  I've met locations that didn't have such an option.  Do you trust the owners and others guests with your stuff you leave in the room, when you're enjoying a hike?

Please, add your own tips in comments.

Sunday, January 3, 2021

E-Books and DeDRM on Ubuntu

 So, my son got me an eBook from eBook.com.  First, I just tried the simplest approach.  Install their official app from Google Play and read it there.  The app is crude but it seemed to work.  Until I changed the font to bigger using the preferences menu. Once, I did this, I noticed the tops and/or bottoms of pages were lost.  If I could slide the page up down a bit to read the missing text, I'd live with it.  But no.  No such feature in the eBooks.com app.  

I wasn't going to guess 1-2 lines of text on each page.  So, it was time to DeDRM the ebook and read it in the Android app that I use usually - Moon Reader.  After all, it's geal in US to remove DRM from an file you legally own.

And here we go.  Oh, I use Linux for the last 2-3 years unless I really have to boot into my old WinXP, Ubuntu 18.04 to be precise. 

Install Wine, ADO and download the eBook

  1. Wine, I installed using the Ubuntu application management UI:


  2.  It installed for me version "wine-3.0"
  3. That was my first contact with Wine.  How do I use it?  I has no UI.  I found that it is quite reliable for some applications.  Here're couple pointers:
    • In the folder ~/.wine (it can be configred to something else, you can have even multiple ones - I just used the default). it creates a whole Windows-like file system.  Look inside the drive-c folder.  Every application installed, is copied to Program Files folder below there.
    • There is winecfg app for configuration and wine uninstaller for, you know, uninstalling applications (command: wine uninstaller).
    • To install from an .msi file, use command: wine msiexec /i msi-file-name
    • To install an application from an installer exe use command: wine installer-file-name.  Once it ran fine, find the executable for the application in Program Files and run a command: wine application-executable-file-name.
  4. For a test, I installed Notepad++ first.  It worked fine.
  5. Then to Adobe Digital Edition.  eBooks.com site provide a link to its installer file.  It installed fine using the tips for wine I have shown above.  It was ADO ver. 1.7 (trying to install ADO ver. 2.0 was unsuccessful - it needs .Net frmework which didn't install via Wine successfully).
  6. I have found the ADO executable in the Wine's Program Files and started it.
  7. The ADO upon first start asked me to register it with Adobe ID which I did.  Just as usually.  
  8. Now, while keeping the ADO running, I requested eBooks.com website to download my eBook.  The only thing I got was an .acm file.  That download didn't trigger any action from the ADO side, as it does on Windows if I remember correctly.  Why?
  9. However, when I requested the .acm file to be opened with a text editot through Ubuntu Files application, ADO woke up and started downloading the eBook.  Hooray!  Although, I don't like magic as it doesn't leave pointers when it doesn't work.
At this point, I was able to read the book on my laptop.  First goal achieved.  However, I don't read books on my laptop.  I need to have them on my Android phone.  So, I needed to remove the DRM from the epub file (I have found it in My Documents/My Digital Editions).

Making Calibre Plugin DeDRM Work

I've used Calibre and its DeDRM plugin before successfully but it was on Windows.  On Linux, it was the first time for me.  Here, we go again:
  1. Installed Calibre using Ubuntu application manager.  It installed version 3.2.1.
  2. From the Apprentice Alf's Blog, download the DeDRM plugin (I chose version 6.8.1 - the most recent version 7+ is for new version of Calibre).  Unpack once.
  3. From the Calibre preferences, choose Plugins and Load from File, choose the DeDRM_plugin.zip (it showed as version 6.8.0).
  4. Now, I restarted Calibre and added the epub to the Calibre collection at which the DeDRM should trigger behind the scene and do its job.  But, it didn't.  When I tried to open the book, I've got the DRM error explaining the book is protected and can't be read.
  5. Now, something was wrong with the DeDRM.  I removed the book from the collection, restarted Calibre in debug mode (see Preferences menu) and retried adding the book.  Immediately after that, I closed Calibre.  When closing, it showed the log file.  
  6. From the log file, I found that DeDRM is trying to run Python using Wine.  I had Python installed on my Ubuntu but it wasn't found.  I need to install it on Wine.
  7. I found version 2.7 installer from Python website and installed with Wine.
  8. Next attempt to DeDRM showed some changes in the debug log.  This time, DeDRM complained it couldn't find PyCrypto package.
  9. Installing this package via command wine pip install pycrypto wasn't successful. But from this website, I found a compiled pycrypto as an exec file (Used the 2.6.1 version with sha512sum since for the asc signature, I wasn't able to find the right public key).  Command wine pycrypto-2.1.0.win32-py2.7.exe did the trick just fine.
At this point, repeating the attempt to add the book to Calibre worked fine.  I could read the book in Calibre.  Then, from the right book details panel that showed the format EPUB, I right clicked on the EPUB link and chose Save as File on Disk.  Select the folder and the books was saved into that folder as a DRM-free epub file.  

Now, transferred the file onto my phone and I can read it complete, the book purchased from eBooks.com.

 


Wednesday, November 20, 2019

JavaScript - My Misc Notes

This blog is managed in 'JS - my notes.md' file

JavaScript - My Misc Notes

Scope

  • Lexical scope: function written within function can access all of the parent's vars and parms.
  • Function can be called before it is defined - before in the text.
  • You can define a regular function anywhere in the code.
  • Pronoun this is calculated when the code is executed. If we call a method that uses this outside of the object it belongs to, this will be undefined.

Modules

  • IIFE way
  • More common: define( [array], object); It comes from CommonJS and RequireJS more or less (see this). If object is a function, its parms are 1 to 1 with elements of the array, each of which specifies a dependency module e.g. 'rs/form/abstract/invoice.controller'. It is guaranted that the function will run only once even if more than one module list this module as their dependency.

Saturday, October 19, 2019

JavaScript ES6 / ES2015 - My Notes

JavaScript ES6 / ES2015 - My Notes

Using ES6 in Prod

  • Supported by modern but not by older browsers
  • So, ES6 needs to be transpiled or multipiled in prod

The let and const

  • const - generates an error when attempted to change value
  • both - block-scoped while var was function scoped (a block is just {...})
  • Now, instead of using IIFE, we can use a block. Variables (and function expressions assigned to variables) marked const or let will be private. While those marked with var will be public.

Strings

  • Template liters (note back-ticks): His name is ${firstName} ${lastName}.

Arrow Functions

  • If we have an array arr1, then arr1.map(el => 2 * el) will return an array of doubled numbers.
  • In fuller format:
    arr1.map((elem, index) => {
      ....
      return ...
    })
  • Arrow functions don't have their own this. They use the this of the function they written in - it's called lexical this.

Sunday, July 21, 2019

Ubuntu - Useful Tricks


  • In Files, to jump to another folder directly, press Ctrl-L and type the path.   Also, it's useful to bookmark the root folder (go to it and bookmark it from the menu)

Friday, July 5, 2019

JavaScript (ES5) - Long-time Java Developer Notes on Differences and Important Features

This highlighting is used code quoted in the text.  All of the below is all EcmaScript5 or earlier versions.


Basics:

  • Strings
    • Single and double quotes - no diff
    • A quote inside: \' or \"

Variables:

  • var names: start with a letter, $ or _.  Can't start with a digit.  Can't be a reserved word.
  • declare a var : var varName;
    This var will be of type undefined without any type.
    Note: a variable used without first defining it, defines and uses a global variable which is equivalent to the code: window.myVar = ...
  • But this one : var varName2 = '234';
    will be of type string
  • And after this : varName2 = 234; (this is variable mutation i.e. it gets a new value)
    The varName2 became a variable of type numeric (dynamic typing)
  • types: string, numeric, xxx or yyy .  No int type.

Conditional processing:
  • A structure I have never met in Java:
       switch(true) {
          case age > 21 && height > 1.65:
             aaa = 123;
          case age >= 65:
             aaa = 222;
      }
  • Falsy: 
    • undefined
    • 0
    • false
    • null
    • NaN
  • Equality operator (==) performs a type conversion (it's called type coersion in JS) so that: 23 == '23' evaluates to true.  Also console.log('he is ' + age + 'years old'); is fine even when age is numeric./
  • Strict operator === means 'the same type and the same value'
  • If you do not know whether a variable exists (that means, if it was declared) you should check with the typeof operator. For instanceif( typeof foo !== 'undefined' ) {...} but there is a function to check it, too.

Objects:

Primitive: a variable contains the value itself.
Object: the variable points to the object which is stored elsewhere.
  • Create objects (4 ways):
    • litera: var aaa = {name: "Ala", age: 53}   // it's an instance of Object() object
    • constructor methods (aka prototypes; not called classes):
      function Person(name, age) = {this.name = name, this.age = age};
      var p = new Person("Ala", 56)
        - it creates an empty objects and calls the constructor function with this set to the new object.
      • A method defined inside the constructor will not be shared among the children but separately recreated in each (memory!).  So, it's often better to Person.prototype.calcAge = function() {...}; instead.  This method will be shared by all children
    • Object.create(protoObject, { age: {value: 36}, fName: {value: 'Pawel'} }); but the 2nd parm is optional.  The value thing is not optional here.
  • Understand objects
    • An object in JS is simply a hashmap with key-value pairs. A key is always a string, and a value  can be anything including strings, integers, booleans, functions, other objects etc.
  • Create object, the minimalist version: var obj = {};
  • Always can extend an object from outside (No immutable objects?): obj['age'] = 56 or obj.age = 56
  • Or add a method
    obj.isAnAdult() { return this.age > 18; }  // the other syntax works, too
  • Functions are always objects (they're 1st class functions).  Create one, minimalist way function  foo() {}; and can add atributes or other methods the usual way: foo.age = 56
  • Summary: Practically everything is an object except primitive types (string, number and boolean), undefined and null (though null is considered an object, too).
  • If you want to know if a member exists independent but don't care what its value is:
    if ('membername' in object) // With inheritance VERIFY IF THIS ONE'S TRUE!!!
    if (object.hasOwnProperty('membername')) // Without in
    heritance
  • Clone: Object.assign(target, source)
    Watch out:  it is actually a merge of source into a target object, but Object.assign({}, source) will create a clone.  And, another warning: it's a shallow clone.
  • Inheritance is done in JS thru Prototype property which all objects have!!!  That property is used for children objects - any property or methods that we want the children objects to have access to, we put inside the Prototype property. The prototype property of object Object is null (here the protype chain stops when JS VM searches for a property or method of an object)

How does JavaScript work?

  • When method execution starts, first its execution context is created.
  • hoisting (during creation of the execution context for a method):
    • all declared functions are created before the execution for that method starts. But only declared function (not function expressions like var age = function(year) { ...}).  
    • thanks to hoisting, I can call functions that are declared later in the code.
    • all variables are created but set to undefined
  • Functions and only functions create a scope
    • Global scope is available to everyone
    • Functions written inside another function have access to the parent scope (or scopes if nested deeper)
  • Two types of functions:
    • regular (or declared) function - Just a function myFnc() {...}.
    • method - a function that is a value of an object (key, value) pair.
  • The this variable is part of the execution context and is set only at the moment when the function is called.  It's set to:
    • for regular functions, this is the Window object even if the function is defined inside of a method.
    • for method functions, the object in which the method is defined.

Interact with the Browser

  • DOM access: 
    • document.querySelector('#playerScore-' + activePlayer).textContent = score
      NOTE: querySelector finds only the first instance of a node satisfying the criteria
    • document.querySelector('.dice').style.display = 'none'
    • document.getElementById('player').classList.toggle('active')
  • Events:
    • Rule: Event gets processed only when the execution stack (where all exec contexts are placed) is empty (ie. all functions return)
    • When this happens the handler for the first of the events waiting in the event queue is called
    • doc.quSel(...).addEventListener('click', function() {....})
      arg1 - event type (see MDN for a table)
      arg2 - callback function

Console in the browser Dev Tools

  • > john - displays info about
  • > console.info(myArray) - displays more info than typing the object name directly
  • __proto__  - link to parent's prototype

Functions

  • IIFE ([ifee], Immediately invoked function expressions: (function (age) { var a = 5; ...})(5); .  The code inside the function is executed but variable a is hidden - data privacy. In JS, anything inside () is an expression.
    • Return from the function above an object with anything to be publicly available outside.
    • It's the module pattern
  • All functions in JS are closures.  Because functions have access to lexically outside scopes and (I think) scopes don't disappear.  Closures remember all vars and all parms of lexically outside functions.
  • Calling functions returned by functions: If fn1 returns a function, we can call it: fn1('John')(25);  where 'John' is an argument of fn1 and 25 is an argument of the functions that fn1 has returned.
  • Given, we have john object with a method presentation(style, timeOfDay) and emily object:
    • Function borrowing: john.presentation.call(emily, 'friendly', 'morning'); will execute the method for emily (every this will point to emily - use null if you don't need to redirect this)
    • Function borrowing with args in an array: john.presentation.apply(emily, ['friendly', 'morning']); 
    • Binding: 
      • var emilyFormal = john.presentation.bind(emily, 'formal'); will return a function with some parms preset (currying).  We can call it: emilyFormal('afternoon');.
      • Binding can also be used to set this for the function.

Friday, June 28, 2019

Building Java Applications with Gradle

Gradle wrapper:

  • In order to make sure you build the project with the same version of gradle as other developers (which can make a big difference), build the application using the wrapper: ./gradlew
    It will start with downloading the right gradle version, unless it's already there.
  • Watch out for running old gradlew for a version like 2.3 with a new java like version 11.  It quits silently without doing anything.

Useful commands:

  • gradle build -x test  -- run build but skip tests

Friday, June 7, 2019

Querying for Data in a Java Spring App - Alternatives


  1. Create a method with a name including all attributes you want to query by in your PersonRepository interface that implements CrudRepository<> (or PagingAndSortingRepository<>)
  2. Create a Specification object and use Spring findAll to find all records matching the Specification.
  3. Use @Query in the PersonRepository and define the query using JQL
  4. Use GraphQL (see for example https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#core.extensions.querydsl)

Monday, June 3, 2019

Unit testing with jUnit5 and Mockito

Mocking for Spring injected dependencies

import org.junit.jupiter.api.Test;

@ExtendWith(MockitoExtension.class)
class Person {
   @Mock
   DependencyA dependencyA;

   // Don't use @InjectMocks if using constructor injection with final dependencies.
   // Mockito can't set the new mocks for each test
   TestedClass target;

   @BeforeEach
   public void setup() {
      // only needed if you do Mockito.when(dependencyA.methodAbc()).thenReturn() or similar
      MockitoAnnotations.initialize(this);  
      target = new TestedClass(dependencyA);
   }

   @Test
   public void testMethodWhatsyourname() {
      // given
      ...
      
      // when
      target.whatsYourName();

      // then 
      ...
   }
}

Monday, May 20, 2019

Java Optional - Good Practice



  • orElseThrow: if personService.getAll() returns an Optional, then:
    return personService.getAll().map(converter::toResource).orElseThrow(
           () -> new NoResourceFound(...)
    );
  • orElse: if personService.getByLastName() returns an optional:
    return personService.getByLastName(lName).orElse(null);

Tuesday, April 30, 2019

Java Streams

Null elements in the stream

I thought, I saw a statement that Java streams filters out the null elements in the stream but the information must have been wrong.  So, if nulls are expected, or just in case, do:

... .filter(Objects::nonNull). ....

Monday, April 29, 2019

Java 9 - What's New In It


Modules

  • defined by file module-info.java in the module root directory
  • defines the module name, which package the module exports and
    what other modules it requires
  • if package org.sjb exports to a module, its subpackage isn't
    exported automatically; it can be exported by any module
  • each package is exported by a single module
  • jlink - packages a modules with all its required modules and the needed parts of the JRE into a standalone app which won't need Java to be installed where it runs
  • unnamed modules - all not defined stuff gets packed into a single unnamed module.  It exports all packages but only unnamed modules can call them.
  • automatic modules ...

Services


Using modules, the client code can receive all available implementations
  of an interface, and choose as one it needs (server and client are in the same JVM;
  it's not about http clients)

Monday, March 18, 2019

jUnit Fun

jUnit and Mockito Fun

More Interesting Elements of Unit Testing and Mocking


  • Verify that a method was called on a mock

    • Verify the parameters the method was called with
  • Return a custom response from a method called on a mock, response based on the parameters of the call
    Mockito.when(myMock.save(any(Person.class))).thenAnswer(i -> {
        Person person = (MyClass) i.getArguments()[0];
        return "Hello, " + person.getFirstName();
    });

Friday, September 14, 2018

AWK - Just Examples with Explanations

Example 1


/ERROR/ { if ($0 !~ /notThisOne/) print NR $0 }


This script prints all lines with the word ERROR but without a word notThisOne.  The original line number is printed in front of each line printed.

Friday, October 13, 2017

Git - Basic Commands

Understanding

The Git repository is a tree of commits each of which keeps a pointer to its parent (for merge commits: two parents) and all of the files modified in this commit.  HEAD, tags and branches are all labels to a node of that tree.

Branches

  • git branch NAME   --- create a branch of the current branch
  • git branch --all  --- list all branches local and remote
  • git checkout -b release-4.16.0 origin/develop   --- create branch release-4.16.0 from the current branch and set tracking to origin/develop
  • git branch -u origin/develop  --- set tracking on an existing branch
  • git branch -d NAME  - delete a local branch but only if it's safe (i.e. we won't loose access to any commit)
  • git branch -D NAME  - force delete a local branch (requires extra permissions; commits to which we may loose access will be available through its ID for next N days (default is 30 days) and it will be garbage-collected after that)
  • git push origin --delete NAME  - force delete a remote branch

Commit

  • git commit  --- committing the changes to local git repo
  • git commit --amend  --- allows to edit the last commit, to edit its message and correct the files you committed
  • git reset --soft HEAD~1 --- undoes the most recent commit without reverting the changes in the files
  • git fetch origin && git reset --hard origin/master --- reset your branch to what it was before any changes and commits done locally.  To save the local commits just in case, do git branch saved-my-commits-here.

Pushing and Pull

  • git add  --- staging files for commit
  • git pull  --- if the current branch is behind the branch it tracks, this command will update it
  • git push origin local-branch:remote-branch  --- push local branch to remote repository origin

Rebase

  •  git rebase origin/develop  --- rebases, which means if the current branch is behind on some commits from origin/develop branch, it will incorporate all of them and place as if they were made earlier than those commits that the current branch is ahead of the origin/develop.
  • git rebase -i HEAD~2  --- interactive rebase, that is a tool to modify commit history.  In most common scenario it is used to squash two or more recent commits into one (though commit --amend can do it, too) but it can also remove commits from the history as well as change their order.  The tool can do lasting damage if you make mistake - use with caution!

Tags

  • git tag v4.23.0  --- adds a tag v4.23.0 to the current node (there is also another, lighter type of tag - I haven't been using it)
  • git push origin v4.23.0  --- pushing a tag to the remote repo

Other

  • git fetch  --- updates the local git repo from the remote repos
  • git status  --- shows the commits that the current branch is ahead and behind with respect to the branch it tracks as well as unversioned and modified files that aren't added to the change set.
  • git log  --- shows a paged list of commits with the most recent first
  • cherrypicking  --- allows to copy a commit from into another branch (important: it's a copy
  • git merge my-other-branch  --- merges my-other-branch into the current branch; use --no-ff if you always want a merge and not just a git pull if the last commit on current branch happens to be an ancestor of the commits on my-other-branch.
  • git mv --- rename or move a file or folder without losing its history (to see its full history afterwards use git log --follow).

Tuesday, September 26, 2017

Docker - All the Magic


Understanding It

  • docker is a history recorded of what changed from the original image that the container started off
  • restart (or stop and start) reverts the container to what the image was, so the container is transient by default
  • it may be also possible to revert by tagging the image (yes!)

Maintenance

When it gets sloooow, and the com.docker.hyperkit takes 20% or 30% of CPU or more, try:
  • consider reducing the # of cpu's enabled
  • prune images not referenced by any container (created
    more than 24h ago):

    docker image prune -a --filter "until=24h"
  • prune containers all stopped containers (older than 24h):
    docker container prune --filter "until=24h"
  • prune networks not used by any container (older than 24h):
    docker network prune --filter "until=24h"
  • and possibly prune volumes not used by currently by any container (make sure you don't need the data on them):
    docker volume prune

Wednesday, April 6, 2016

AWK Scripts - Examples

Example 1:

{
  if (match($0,/stat\.X[0-9][0-9][0-9]/)) tab = substr($0,RSTART+6,RLENGTH-6);
  if (tab + 0 >= 70 && tab + 0 <= 120) { print tab; }
}

Script does:
  • For every line like statA.X023, sets the variable 'tab' to the number, here 023
  • outputs the number if it is between 70 and 120

Friday, January 1, 2016

Playing an Audio ISO and Burning it into a CD

Tools that worked nicely for me:


  • To install the ISO on Windows to platy and copy MP3 of it: VirtualCloneDriver 5.4.9.0 (downloaded from SkySoft Download)
  • To burn: CyberLink Power2Go v. 5
What didn't work:
  • MicroSoft Virtual CD-ROM Control Panel v. 2.0.1.1
    Problem: driver installation; it's a tricky piece of software, doesn't see the driver file even it was placed where told to - file was there but the software filtered it out, somehow, even when run an admin
Environment: Windows 7

Thursday, November 12, 2015

Update in PostgresSQL Using the Command Line Tool - PSQL

The command:

psql -h hostname -d database -U username -W --echo-queries -f script-file-name.sql

where:

-W - to request psql to ask for password (rather then assume no-password)-h  - PostgreSql server host name or ip
-f  - file with the SQL script to execute on the database
 --echo-querries - shows the currently executed query for easier debugging of the script

Wednesday, October 28, 2015

Install Puppy Linux on my Old ThinkPad R60

Version: Slacko Puppy 5.7

  • Problem: Wi-Fi not working. Solution:
  • First: rfkill list
  • if it says softblock yes, try Fn F5. If it doesn't help do: sudo rfkill unblock wifi; sudo rfkill unblock all
  • Then:

# cd /lib/firmware/
# cp iwlwifi-3945-2.ucode iwlwifi-3945-1.ucode
# ifconfig wlan0 up

And try to connect.