CODE FOR A FICTION

Syntax of Imagination.
  • Baner imager of Code for a fiction

    Welcome to CODE OF A FICTION

    Syntax of Imagination” melds the precision of coding with the vastness of creative thought, crafting a digital narrative where every command is a creation.

Monday, April 15, 2024

How do we capture the Activation/Deactivation Events on AEM Publisher Instance.




In Adobe Experience Manager (AEM), content is replicated from the author instance to the publish instances whenever authors publish anything. This process can be thought of as copying a page to the publish instance in layman’s terms.

When we want to capture these events on the publish instance while writing our event handlers, we might get confused and use ReplicationAction.EVENT_TOPIC. However, this is not correct. The key difference lies in the event topics for the author and publisher instances. For the author's instance, the event topic is com.day.cq.replication.ReplicationAction, while for the publisher instance, the event topic is com.day.cq.replication.ReplicationEvent.

The names themselves give us a fair idea of their roles. In the author instance, the replication process is triggered or actually started. We configure replication agents on the author instance itself. On the other hand, the publish instance is where we receive the pages or assets. Therefore, the author instance is associated with the replication action, and the publish instance is associated with the replication event. I hope this clarifies the difference! 😊

Here is a sample code : 
import com.day.cq.replication.ReplicationEvent;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;

@Component(
    service = EventHandler.class,
    immediate = true,
    property = {
        "event.topics=" + ReplicationEvent.EVENT_TOPIC
    }
)
public class CustomReplicationEventHandler implements EventHandler {

    @Reference
    private ResourceResolverFactory resolverFactory;

    @Override
    public void handleEvent(final Event event) {
        ReplicationEvent replicationEvent = ReplicationEvent.fromEvent(event);

        if (replicationEvent.getType().equals(ReplicationEvent.Action.ACTIVATE) || 
            replicationEvent.getType().equals(ReplicationEvent.Action.DEACTIVATE)) {
            try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(null)) {
                // Your custom logic here
                // For example, you might log the path of the replicated resource:
                System.out.println("Resource replicated: " + replicationEvent.getPath());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}


In this example, I have created an OSGi component that listens for replication events on publisher. When a replication event occurs, the handleEvent method is called. Inside this method, I am checking if the replication event type is either ACTIVATE or DEACTIVATE. If it is, we’re logging the path of the replicated resource.
Share:

Thursday, March 28, 2024

How to Add externally hosted JS/CSS in Blogger Template.



I recently started writing blogs on blogger.com, and I find myself struggling with managing JavaScript and CSS files on blogger template as I was using a custom template Editing them directly in the Blogger template can be a hassle, especially when the files get large.(I know most people would not customize there templates frequently but for a new starter it would take time till whole look and feel of their template in a stable state) It’s also not the most efficient way to handle these resources. So, I started exploring ways to move all my JS/CSS to external files. This way it would be much easier for me to manage my template code. I found an excellent solution – jsDelivr and Github! 

jsDelivr is a free, open-source CDN (Content Delivery Network) that provides a fast delivery of files hosted on GitHub. It’s exactly what I needed! 

Step 1: Minify JS/CSS Files 

Before we start, it’s important to note that we’ll be using Node.js (Node Package Manager) for this process. Then the first thing I did was to set up my package.json file. Here’s what my package.json file looks like:

{
  "name": "cfaf",
  "version": "1.0.0",
  "description": "A project using Gulp to minify js/css",
  "main": "gulpfile.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/rahulrai89/cfaf.git"
  },
  "keywords": [
    "gulp",
    "automation",
    "build"
  ],
  "author": "Rahul",
  "license": "ISC",
  "bugs": {
    "url": "https://github.com/rahulrai89/cfaf/issues"
  },
  "homepage": "https://github.com/rahulrai89/cfaf#readme",
  "browserslist": [
    "ie >= 10",
    "ie_mob >= 10",
    "ff >= 30",
    "chrome >= 34",
    "safari >= 7",
    "opera >= 23",
    "ios >= 7",
    "android >= 4.4",
    "bb >= 10"
  ],
  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-autoprefixer": "^7.0.1",
    "gulp-csso": "^4.0.1",
    "del": "^6.0.0",
    "gulp-sass": "^5.0.0",
    "sass": "^1.43.4",
    "gulp-uglify": "^3.0.2"
  }
}
In the devDependencies section, you can see that I’m using Gulp, along with several Gulp plugins. Gulp is a task runner that we can use to automate common tasks in the development process. In this case, I’m using it to compile, autoprefix, and minify my SASS files into CSS, as well as to minify my JavaScript files. I minified my JS/CSS files using Gulp. Here’s how I did it:

Create gulpfile.js  

// Import the required modules
const { src, dest, series, parallel } = require('gulp');
const autoprefixer = require('gulp-autoprefixer');
const csso = require('gulp-csso');
const del = require('del');
const sass = require('gulp-sass')(require('sass'));
const uglify = require('gulp-uglify');

// Gulp task to minify CSS files
function styles() {
  return src('src/sass/styles.scss')
    // Compile SASS files
    .pipe(sass({outputStyle: 'compressed'}).on('error', sass.logError))
    // Auto-prefix css styles for cross browser compatibility
    .pipe(autoprefixer())
    // Minify the file
    .pipe(csso())
    // Output
    .pipe(dest('secure/css'));
}

// Gulp task to minify JavaScript files
function scripts() {
  return src('src/js/**/*.js')
    // Minify the file
    .pipe(uglify())
    // Output
    .pipe(dest('secure/js'));
}

// Clean output directory
function clean() {
  return del(['secure']);
}

// Gulp task to minify all files
exports.default = series(clean, parallel(styles, scripts));

Run

npm install

Step 2: Run Gulp Tasks

Next, I ran the command gulp in my project directory. This executed the default task, which in turn ran my clean, styles, and scripts tasks. The minified CSS and JS files were then outputted to the secure/css and secure/js directories, respectively.
gulp

Step 3: Commit Minified Files to GitHub

After running the Gulp tasks, I pushed these minified files to my GitHub repository. 

Step 4: Use jsDelivr to Serve Minified Files 

At first why we need this step anyway - When you access a file through GitHub’s raw link, it’s typically delivered with a “text/plain” Content-Type Header. This is a standard way for servers to inform your browser about the type of content being sent. However, modern browsers are quite particular about how they interpret and process different types of content. When they receive a file labeled as “text/plain”, they treat it as plain text, regardless of its actual content. This means that even if the file contains CSS, JavaScript, or HTML code, the browser won’t recognize it as such. It will simply display it as plain text, which isn’t very useful for our purposes. 

This is where jsDelivr comes in. It serves files with the appropriate Content-Type Headers, ensuring that browsers interpret them correctly. So, a CSS file is served as “text/css”, a JavaScript file as “application/javascript”, and so on. This allows us to use these files as intended in our Blogger template. 

Instead of using the raw content URLs of my minified CSS and JS files, I used jsDelivr. Here’s how it works: 
The base URL for the jsDelivr CDN service is https://cdn.jsdelivr.net/gh/{username}/{repo}/. You just replace {username} with your GitHub username and {repo} with the name of your repository. So, in my case your GitHub username is rahulrai89 and my repository name is cfaf, the URL would be https://cdn.jsdelivr.net/gh/rahulrai89/cfaf/. 

This way, I was able to link to my minified CSS and JS files directly from my Blogger template, like so:

<link href="https://cdn.jsdelivr.net/gh/rahulrai89/cfaf/secure/css/styles.css" rel="stylesheet" type="text/css"></link>
<script src="https://cdn.jsdelivr.net/gh/rahulrai89/cfaf/secure/js/main.js"></script>
If you’re interested, you can find the source code of the above and my blogger template on my GitHub repository. Just head over to https://github.com/rahulrai89/cfaf And that’s it! Now, managing my JS/CSS files for my Blogger template is a breeze. I hope you find this guide helpful. If you have any questions, feel free to ask.
Share:

Saturday, March 23, 2024

Creating North Indian Style Vedic Astrology Charts with Python and SVGWRITE

North India Chart Generation


In this blog post, I will share with you how to create North Indian-style Vedic astrology charts using Python. The tools I will be using will be the svgwrite library, a powerful resource that enables us to craft SVG (Scalable Vector Graphics) files programmatically. Let’s start.

Imports

The Python libraries used in our code are: 
  • svgwrite: This library provides an interface for creating SVG files.
  • math: This library provides mathematical functions. 
  • random: This library is used to generate random numbers. 

Code

The code begins by importing the necessary libraries:

import svgwrite
from svgwrite import cm, mm
import math
import random
Next, this creates a new SVG document using svgwrite.Drawing. The size of the drawing is set to 100% of the viewport, and the SVG profile is set to ‘full’, which allows for the most features: 


dwg = svgwrite.Drawing('astrology_chart.svg', size=("100%", "100%"), profile='full') 

This would set the width and height of the SVG to ‘100%’, which means the SVG will take up 100% of the width and height of its container. The viewBox attribute is used to specify the aspect ratio and coordinate system of the SVG. In this case, we set it to ‘0 0 800 600’, which means the width and height of the SVG’s coordinate system are 100 units.

# Set the size of the SVG to a percentage of the viewport
dwg.attribs['width'] = '100%'
dwg.attribs['height'] = '100%'
dwg.attribs['viewBox'] = '0 0 800 600'
This would define a linear gradient and add it to the defs section of the SVG. This gradient will be used to fill the polygons that represent the houses in the chart:

gradient = svgwrite.gradients.LinearGradient(start=(0, 0), end=(0, 1), id="grad")
gradient.add_stop_color(0, 'white')
gradient.add_stop_color(1, '#f0f3bf')
dwg.defs.add(gradient)
The houses in the chart are represented as polygons. The points for each polygon are defined, and then the polygon is created and added to the SVG drawing:

points_h1 = [(100,225), (200,300), (300,225), (200,150)]
h1 = svgwrite.shapes.Polygon(points_h1, fill="url(#grad)")
dwg.add(h1)
This process is repeated for each of the 12 houses. The centers of the polygons (houses) are defined in the centers list:

centers = [
    (190, 75),  # 1st house
    (100, 30),   # 2nd house
    (30, 75),   # 3rd house
    (90, 150),  # 4th house
    (30, 225),     # 5th house
    (90, 278),  # 6th house
    (190, 225),  # 7th house
    (290, 278),  # 8th house
    (360, 225),    # 9th house
    (290, 150),  # 10th house
    (360, 75),  # 11th house
    (290, 30),   # 12th house
]
Each tuple in the list represents the (x, y) coordinates of the center of a house. The coordinates are defined in the SVG’s coordinate system. The placeholders for the planets are generated in a circular arrangement around the center of each house. This is done in the following part of the code: Next, we randomly assign each planet to a house. The planets are represented as text elements, which are placed in a circular arrangement within each house:

for i, center in enumerate(centers):
    house_planets = houses[i]
    for j, planet in enumerate(house_planets):
        angle = 2 * math.pi * j / len(house_planets)
        x = center[0] + radius * math.cos(angle)
        y = center[1] + radius * math.sin(angle)
        color = colors[planets.index(planet)]
        dwg.add(dwg.text(planet[:2], insert=(x, y), font_size='11px', fill=color))
In this part of the code, I first iterated over the list of centers, which are the center points of each house. For each house, i would get the list of planets assigned to that house. Then i iterated over this list of planets. For each planet, i calculated an angle based on the index of the planet in the list and the total number of planets in the house. This angle is used to calculate the x and y coordinates of the planet’s position within the house. The position is calculated such that the planets are arranged in a circular pattern around the center of the house. Finally, the SVG document is saved:

dwg.save()
After running the Python script, an SVG file named ‘astrology_chart.svg’ will be generated. This file contains a graphical representation of the North Indian style Vedic astrology chart. The chart consists of 12 houses, each represented by a polygon. Each house contains one or more planets, represented by text elements. The planets are arranged in predefined placeholder within each house. The size and position of the elements in the chart are calculated dynamically, so the chart can be easily customized by modifying the code. Open the SVG file in a web browser or image viewer to see the generated chart. The chart should look similar to the image provided below.


You can find the complete code for generating the North Indian style Vedic astrology chart on my GitHub GIST. Feel free to clone, and explore the code in more detail. If you have any questions or suggestions, don’t hesitate to post. Happy coding!

Additional Details 

The colors of the planets are defined in the colors list. Each color corresponds to a planet in the planets list. The colors are then used to fill the text elements that represent the planets. The houses are randomly generated for testing purposes. In a real-world application, i would replace this with the actual house data. 

Possible Improvements 

While this code serves its purpose, there are several ways it could be improved: 
  • Modularization: The code could be broken down into functions to improve readability and reusability.
  • Error Handling: The code currently does not handle any errors or exceptions. Adding error handling would make the code more robust. 
  • Customization: The code could be modified to allow for more customization, such as different color schemes or chart styles. 
Share:

Friday, March 22, 2024

Getting Started with Swiss Ephemeris in Python for Astrological Calculations

Swisseph

The Swiss Ephemeris (swisseph) library is a powerful tool for high-precision astronomical and astrological calculations. Here are some reasons why you might want to use it:

  1. High Precision: Swiss Ephemeris is based on the DE431 ephemeris from NASA’s Jet Propulsion Laboratory (JPL), which is one of the most accurate ephemerides available. This makes it suitable for applications that require high precision, such as astrology, astronomy, and celestial navigation.
  2. Wide Time Range: Swiss Ephemeris covers a wide time range, from 13201 BCE to 17191 CE. This makes it useful for historical research, as well as for predicting future celestial events.
  3. Comprehensive Features: Swiss Ephemeris provides a wide range of features, including the calculation of planetary positions, houses, aspects, transits, solar and lunar returns, and more. It also provides functions for calculating sunrise and sunset times, as well as other astronomical phenomena.
  4. Ease of Use: Swiss Ephemeris provides a simple and intuitive API, making it easy to use in your applications. It also provides bindings for several programming languages, including Python, which makes it accessible to a wide range of developers.
  5. Open Source: Swiss Ephemeris is open source, which means you can use it for free in your applications, and you can also contribute to its development if you wish.Installation 

Swisseph can be installed in Python using pip, which is a package manager for Python. You can install it by running the following command in your terminal:

pip install pyswisseph
Make sure that you have pip installed and that Python is in your system’s path. 

Basic Usage 

Once you have installed swisseph, you can import it in your Python script as follows:

import swisseph as swe
Before making any calculations, it’s important to set the Ayanamsha. For Vedic astrology, N.C. Lahiri is commonly used:

swe.set_sid_mode(swe.SIDM_LAHIRI)
You can calculate the position of a planet using the calc_ut function. For example, to calculate the position of the Sun:

jd = swe.julday(2024, 3, 21)
xx, ret = swe.calc_ut(jd, swe.SUN)
The calc_ut function returns two values: xx and ret. xx is a list that contains the longitude, latitude, distance, and speed of the planet. ret is a flag that indicates whether the calculation was successful. 

Advanced Usage 

Swisseph can also calculate the Ascendant (Lagna), Rasi (Zodiac sign), planetary positions, houses of each planet, sunrise and sunset times, Tithi (Lunar day), and Vara (Day of the week) for a specified date, time, and location. This can serve as the foundation for a more complex astrological software. Here’s an example script that demonstrates these calculations:

import swisseph as swe
import json
from datetime import datetime

# Set the path to the Swiss Ephemeris data files
swe.set_ephe_path('ephe')

# Set the Ayanamsha to N.C. Lahiri
swe.set_sid_mode(swe.SIDM_LAHIRI)

# Get user input
name = input("Enter name: ")
dob = input("Enter date of birth (YYYY-MM-DD): ")
tob = input("Enter time of birth (HH:MM:SS): ")
place_of_birth = input("Enter place of birth: ")
latitude = float(input("Enter latitude: "))
longitude = float(input("Enter longitude: "))

# Parse the date and time of birth
year, month, day = map(int, dob.split('-'))
hour, minute, second = map(int, tob.split(':'))

# Calculate Julian Day
jd = swe.julday(year, month, day, hour + minute/60 + second/3600)

# Calculate the Ascendant using Equal house system
asc = swe.houses(jd, latitude, longitude, b'E')[0][0]

# Calculate the Rasi (Zodiac sign)
rasi = int((asc % 360) / 30)

# Calculate planetary positions and houses
planets = ['Sun', 'Moon', 'Mercury', 'Venus', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune', 'Pluto']
planet_positions = {}
planet_houses = {}
for i, planet in enumerate(planets):
    xx, ret = swe.calc_ut(jd, i, swe.FLG_SPEED)  # Include velocities in the output
    planet_positions[planet] = xx[0]  # Longitude of the planet
    planet_houses[planet] = swe.house_pos(asc, latitude, 'E', xx[0], xx[1])  # House of the planet

# Calculate sunrise and sunset
next_sunrise = swe.rise_trans(jd, swe.SUN, geopos=(longitude, latitude, 0), rsmi=swe.CALC_RISE)[1][0]
next_sunset = swe.rise_trans(jd, swe.SUN, geopos=(longitude, latitude, 0), rsmi=swe.CALC_SET)[1][0]

# Convert sunrise and sunset times to date-time format
next_sunrise = datetime.fromtimestamp(swe.revjul(next_sunrise)).strftime('%Y-%m-%d %H:%M:%S')
next_sunset = datetime.fromtimestamp(swe.revjul(next_sunset)).strftime('%Y-%m-%d %H:%M:%S')

# Calculate Tithi (Lunar day)
moon_long = swe.calc_ut(jd, swe.MOON)[0][0]
sun_long = swe.calc_ut(jd, swe.SUN)[0][0]
tithi = int((moon_long - sun_long) % 360 / 12) + 1

# Calculate Vara (Day of the week)
vara = int((jd + 1) % 7)
vara_names = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']

# Create a dictionary to store the results
data = {
    "name": name,
    "date_of_birth": dob,
    "time_of_birth": tob,
    "place_of_birth": place_of_birth,
    "latitude": latitude,
    "longitude": longitude,
    "ascendant": asc,
    "rasi": rasi,
    "planet_positions": planet_positions,
    "planet_houses": planet_houses,
    "next_sunrise": next_sunrise,
    "next_sunset": next_sunset,
    "tithi": tithi,
    "vara": vara_names[vara]
}

# Convert the dictionary to a JSON string
json_data = json.dumps(data, indent=4)

# Print the JSON string
print(json_data)
This script demonstrates how to use swisseph to perform a variety of astrological calculations. It serves as a good starting point for developing more complex astrological software. 

NOTE 

The swe.set_ephe_path('ephe') function is used to set the path to the directory containing the Swiss Ephemeris data files. These data files are necessary for the Swiss Ephemeris library to perform astronomical calculations. 
The argument 'ephe' is the path to the directory containing the data files. This can be an absolute path or a relative path. In this case, 'ephe' is a relative path, which means that the ephe directory is located in the same directory as the Python script. Here’s an example of how to use this function:

import swisseph as swe

# Set the path to the Swiss Ephemeris data files
swe.set_ephe_path('ephe')

# Now you can use other functions from the Swiss Ephemeris library
jd = swe.julday(2024, 3, 21)
xx, ret = swe.calc_ut(jd, swe.SUN)

print(f"The position of the Sun on March 21, 2024 is {xx[0]} degrees.")
In this example, the swe.set_ephe_path('ephe') function is called before any other Swiss Ephemeris functions. This ensures that the Swiss Ephemeris library knows where to find the data files it needs to perform calculations. 

Please note that you need to have the Swiss Ephemeris data files in the ephe directory for this to work. If the data files are not found, the Swiss Ephemeris library will not be able to perform calculations and will raise an error. You can download the Swiss Ephemeris data files from the Astrodienst website or GITHUB. Please note that this is a very basic calculation and may not be accurate for all purposes. For more accurate calculations, consider using a library specifically designed for Vedic astrology.
Share:

Wednesday, March 20, 2024

Installing SSL on WSL2 Apache

Securing Your Local Development Environment 

Install SSL using merk on WSL2 and Ubuntu


In the world of web development, ensuring the security of your local environment is as crucial as securing a live server. Implementing SSL (Secure Sockets Layer) on your local Apache server running on Windows Subsystem for Linux (WSL2) with Ubuntu can seem daunting, but it’s a vital step towards a more secure development process. Here’s a step-by-step guide to get you started. 

Step 1: Setting Up WSL2 and Apache Before diving into SSL, make sure you have WSL2 installed and running on your Windows machine. If you haven’t already, you can install it by following the official Microsoft documentation. Once WSL2 is up and running, install Apache on your Ubuntu distribution using the following commands:

sudo apt update
sudo apt install apache2
Step 2: Installing mkcert mkcert is a simple tool that makes it easy to create locally trusted development certificates. Install mkcert on both your Windows and WSL2 environments. On WSL2, you can use Homebrew:

brew install mkcert
Or On WSL2 as root

wget https://github.com/FiloSottile/mkcert/releases/download/v1.4.2/mkcert-v1.4.2-linux-amd64
mv mkcert-v1.4.2-linux-amd64 mkcert
sudo chmod +x mkcert
cp mkcert /usr/local/bin/
On Windows, you can use Chocolatey to install mkcert:

choco install mkcert
mkcert -install 
setx CAROOT "$(mkcert -CAROOT)"; If ($Env:WSLENV -notlike "*CAROOT*") { setx WSLENV "CAROOT/up:$Env:WSLENV" }
This will set the CAROOT environment variable on the WSL2 side to point to the Windows CAROOT, so your Windows browser can trust sites running in WSL2. 

Back on WSL2, you can verify the constant by typing:

mkcert -CAROOT
You will see a result something like this:

/mnt/c/Users/User_Name/AppData/Local/mkcert`
Step 3: Generating SSL Certificates With mkcert installed, generate your local CA and SSL certificates. Run the following command in your Powershell terminal:

mkcert localhost 127.0.0.1 ::1
This will create SSL certificates for localhost that you can use with Apache. 

Step 4: Configuring Apache to Use SSL Now, you need to configure Apache to use the SSL certificates generated by mkcert. Edit the default SSL configuration file:

sudo vim /etc/apache2/sites-available/default-ssl.conf
Update the SSLCertificateFile and SSLCertificateKeyFile directives to point to your newly generated certificates: 

SSLCertificateFile /mnt/c/Users/YOUR_WINDOWS_USERNAME/AppData/Local/mkcert/localhost+3.pem
SSLCertificateKeyFile /mnt/c/Users/YOUR_WINDOWS_USERNAME/AppData/Local/mkcert/localhost+3-key.pem
Step 5: Enabling SSL Module and Site If you haven’t already enabled the SSL module and site in Apache, do so with the following commands:

sudo a2enmod ssl
sudo a2ensite default-ssl.conf
sudo service apache2 restart
Step 6: Testing Your Configuration Open your browser and navigate to https://localhost. You should see your Apache default page served over HTTPS. If you encounter any issues, double-check your configuration files and certificate paths. 

Conclusion By following these steps, you’ve successfully installed SSL on your local Apache server running on WSL2 with Ubuntu. This setup not only enhances your development environment’s security but also allows you to test SSL implementations before deploying to production. Remember, while self-signed certificates are great for development, they’re not suitable for production environments. For live websites, always obtain SSL certificates from a trusted CA. For more detailed instructions and troubleshooting, you can refer to community-driven resources and discussions, such as those found on Stack Overflow and other developer forums. 

Happy secure coding!
Share:

Comments

Belive in yourself

Code for a fiction