text:
Posted inThe Indy List
Indie in D.C.: Handmade Habitat Edition
"My cats would do wild things like walk through the sewing machine while I was sewing."
by Kaarin Vembar May 18th, 2018 August 28th, 2020
Credit: Kaarin Vembar
Amina Ahmad is the owner of Handmade Habitat. She makes all-natural soy candles and beauty products. She started her business as a vendor at local markets and now has a studio at Off the Beaten Track Warehouse in Northeast D.C. You can find her at handmadehabitat.co or on Instagram @handmadehabitat.
Your business has grown over eight years. Can you tell me about that growth process?
When I was first doing markets I was selling mostly clothing and bags. It was under a different name.
What was the name?
It was Cats and Crafts by Amina. It was horrible. I had this blog called "Of Cats and Crafts." And it was me sewing in my house. My cats would do wild things like walk through the sewing machine while I was sewing. I started the blog first and I was like, "Well, I should start doing markets." I couldn't come up with a name so I just transitioned that name to the business. It became Handmade Habitat in 2011 or 2012. Everything that I made at that point was an experiment. I experimented with candles back then, and they started selling really well at markets. I always thought of the business at that point as: "Let's see what this can do. Can it sustain my crafting hobby? Can it sustain paying a little bit of my rent?" The candles were doing really well and from a business model perspective moving in that direction made a lot of sense.
What is your philosophy around why you make your candles the way you do?
When I first started making candles I was an environmental science major in college. There was a lot of new research at the time about the toxicity of a lot of traditionally made candles. My candles are all made from soy wax, which is a renewable resource, and it's made in the U.S. It's also very clean burning.
It doesn't release carcinogens and harmful additives into your home air quality. A lot of other waxes have those types of additives in them. There are a lot of petroleum-based candles. People don't realize that a paraffin-based candle is really made from a petroleum byproduct. My candles are made with a soy wax, which is a lot cleaner burning and burns longer just naturally than traditional candles. My candles are all scented with essential oils and all-natural botanical fragrance oils—no synthetics added and they are phthalate-free. The wicks are made with cotton and recycled paper. So they burn cleanly, too. Because a lot of candle wicks will have lead in them.
Oh, I had no idea!
Yeah, which is actually only illegal in California. It's legal everywhere else. If you ever have a candle wick that's like very pointy—or if you pull it down and you see a little metal piece in it—it's lead.
One thing you have been able to do as an entrepreneur is to get your products into other stores.
A lot of it is based on relationships, which is one thing that I really love about D.C. There are a lot of people in D.C. who have stores now that I've known from the market circuit for years. It's been really great to see them get spaces. And it's been really great to see them pull in other makers that they know from their community. So it's really about finding these good relationships with people. Because in business, that's really—it's really all you have, your ability to keep consistent relationships with people.
You have popped around a bit. You worked out of your house. You were at the Arts Walk at Monroe Street Market. Now you are at Off the Beaten Track. Why you have moved around and what that has meant for your business?
I was working out of my house until 2015. At that point we were planning on downsizing apartments because our rent was getting out of hand, as things do in this area. We moved into an apartment that was significantly smaller and it was really not possible to run the business out of there anymore. It was the point when I was like, "I need to grow and I need space to grow." I really wanted a studio space. I looked around everywhere in D.C. I interviewed for a space at the Arts Walk, but I didn't get it. Instead they were like, "Maybe if you do this pop-up something will open up by the time you leave." Which didn't happen. So I did a pop-up there. I was subletting space for a few months. Then I shared space with a different artist on the Arts Walk. Then in May 2016 a space opened up here.
Your journey to get here has been really amazing. You did it in this natural way that makes sense for your own process.
As an entrepreneur you are always so busy that you don't always stop to appreciate it. But I'm totally self-funded. Like the only thing—my mom bought me my first tent when I did my first craft show ever. We went to Kmart and she bought me a tent and two tables because I was 20 years old and had no money. But with the business, this has been completely self-funded the whole time. And it probably would have been easier if I had money to be like, "Oh, I need this, this, and this." But it really takes time to figure out what direction you are going in and then you don't really waste money that way.
D.C. is really supportive of its makers. I feel like other cities are starting to copy the model because they've seen that the makers really like it and everybody just—it makes your city cooler when you're really into your local scene. I feel like I serve a population that's overstressed and overworked.


text:
Q: WPF - Best way to initialize Notification Icon without breaking MVVM standards I am fairly new to the MVVM Architecture, but have developed a handful of applications using MVVM and the Microsoft Community Toolkit Library.
I am currently developing an Event Driven application which monitors various different LogFiles and if an issue is flagged a Custom Notification Icon pops up on the users screen.
I want to abide fully by MVVM Standards, but am struggling to figure out how I could instantiate the Notification User Controls without doing this from a VM.
Due to the fact each Notification User control will look the same, and have the same information within it, I have opted to use one Viewmodel for each Notification Control. This is where the Problem arises.
public MainNotifcationViewModel(NotificationHub notiHub, TaskbarIcon tb)
{
    //Taskbar Definition
    _tb = tb;

    //Notification Hub Definition
    _notiHub = notiHub;
    notiHub.NotificationRecieved += NotiHub_NotificationRecieved;
    Debug.WriteLine(notiHub.listOfFileMonitors.Count);
    WeakReferenceMessenger.Default.Register<ChangeConfigMessage>(this, (r, m) =>
    {
        GetConfig(m.Value);
    });
}
[RelayCommand]
private async Task GetConfig(Configuration value)
{
    Debug.WriteLine(value);
    _notiHub = new NotificationHub(value);
    //Restart Notification Hub with new Config
}
private void NotiHub_NotificationRecieved(object? sender, Noti.Notification.Hub.Data_Models.Notification.NotificationDetails e)
{
    switch (e.Type)
    {
        case NotiType.Logfile:
            Application.Current.Dispatcher.Invoke(new Action(() => {
                _tb.ShowCustomBalloon(new LogfileNotification(e), PopupAnimation.Scroll, 5000);
            }));
            break;
    }
}

Above, you will see the Viewmodel I have instantiated (within the App.Xaml of my application, instead of as a DataContext, for testing purposes). This Viewmodel Triggers the "Monitoring Part" of my application, which waits for changes to a file, and triggers the notiHub.NotificationRecieved Event. This Event then triggers a method, which displays my custom Notification Icon.
I have got this to work Flawlessly by passing in the event details into the UserControl via a Constructor (See code below).
public partial class LogfileNotification : UserControl
{
    public LogfileNotification(NotificationDetails notiDetails)
    {
        TimeStamp = notiDetails.TimeRecieved.ToLongTimeString();
        NotiType = notiDetails.Type.ToString();
        Message = notiDetails.Message;
        Status = notiDetails.Status.ToString();
        NotiName = notiDetails.Name;
        InitializeComponent();
    }
    public string NotiType { get; set; }
    public string TimeStamp { get; set; }
    public string Message { get; set; }
    public string Status { get; set; }
    public string NotiName { get; set; }
}

The UserControl can takes then displays these values within the Notification (by setting it's code behind as the DataContext).
DataContext="{Binding RelativeSource={RelativeSource Self}}"

The Problem I have with this part of the application, is that is does not abide at all by MVVM Standards. Due to what would be the ViewModel, calling the View.
Has anyone got any ideas on how I could display these Notification UserControls, and set a dataContext for them, without breaking any MVVM Standards.
Any Suggestions would be appreciated :D

redpajama_set_name: RedPajamaStackExchange


Follow this easy 14 step checklist to make sure your Skype interviews run smoothly every time.
Skype interviews require the right etiquette, dress code and questions. Not to mention making sure your recording gear works properly and you actually hit record. Learn what to do before, during and after a Skype interview.
Use this template to craft your own Skype interviews.
The Skype Interview Template is free and licensed under Creative Commons License, Attribution 3.0. This means you may edit or build upon the work and even use it commercially, but you must give the original author proper attribution. Thank you!
Adam Franklin and Toby Jenkins are the authors of Web Marketing That Works. They host an iTunes podcast and are the founders of the marketing firm Bluewire Media. They are recognised entrepreneurs, bloggers and speakers, and have released over 37 free templates to an active marketing community of over 15,606 people.


text:
West Virginia Paraquat Lawsuit Attorney
Significant research suggests that the chemical Paraquat may increase the risk of Parkinson's disease. If you were diagnosed with Parkinson's disease after Paraquat exposure, a West Virginia Paraquat lawsuit attorney at Shapiro Legal Group, PLLC can help. Our Paraquat lawyers can help you hold Paraquat manufacturers accountable and secure the compensation you need to pay for your losses.
Why Hire Shapiro Legal Group, PLLC for Your West Virginia Paraquat Lawsuit?
Our Paraquat lawsuit lawyers represent clients across the United States, including West Virginia. We will partner with leading firms to ensure that you have the representative you deserve.
Our firm has recovered millions of dollars in successful settlements and jury verdicts for our clients. We will advocate aggressively for your maximum compensation.
Our firm will maintain an open line of communication with you from consultation to settlement. You will always be able to ask questions and receive timely updates.
Although it is banned in several other countries, Paraquat is a widely used herbicide in the United States. A highly toxic substance, farmers, and other commercial users must have a license to purchase and use it. Multiple products contain Paraquat, including Para-Shot 3.0, Firestorm, and Blanco.
Multiple studies suggest that Paraquat may cause Parkinson's disease, according to the Michael J. Fox Foundation. For example, a study of farmers who handled Paraquat found a 200% higher risk of developing this condition. A study of California residents who were exposed as teens or young adults had a 200–600% higher risk.
Diagnosed with Parkinson's disease? Speak with a West Virginia Paraquat lawyer at Shapiro Legal Group, PLLC to learn more about your legal options.
Parkinson's disease is categorized into five stages based on symptom severity:
Stage 1: Mild symptoms that affect one side of the body
Stage 2: Worsening symptoms that affect both sides of the body
Stage 3: Mid-stage symptoms characterized by increased falls and slowed movements
Stage 4: Severe and limiting symptoms that make it difficult to live alone
Stage 5: The most severe stage with advanced and debilitating symptoms
Common signs of Parkinson's disease include the following:
Slower movements
Tremors and shaking
Balance difficulties
Loss of automatic movements, like blinking
What Is the Statute of Limitations for Paraquat Lawsuits in West Virginia?
If you are diagnosed with Parkinson's disease and believe Paraquat is responsible, it is important to act quickly. In West Virginia, you or your West Virginia Paraquat attorney must file your lawsuit within two years of the date of your diagnosis or the court will likely dismiss your claim, preventing you from recovering compensation.
West Virginia Paraquat Lawsuits
Through a West Virginia Paraquat lawsuit, you can hold the herbicide's manufacturers accountable for the losses you suffered, such as the following:
Lost wages and loss of future earnings
Disability accommodations, such as live-in care
Physical and emotional pain and suffering
In these situations, you need an attorney on your side who can advocate aggressively for your best interests. The West Virginia Paraquat lawsuit lawyers at Shapiro Legal Group, PLLC have over 20 years of experience in dangerous and defective product litigation and will leverage their knowledge to fight for your best interests.
Schedule a Free Consultation With a West Virginia Paraquat Lawyer
Are you eligible for litigation against Paraquat manufacturers? The lawyers at Shapiro Legal Group, PLLC can represent your claim. Contact us today and discuss your legal options with a West Virginia Paraquat lawsuit attorney.

redpajama_set_name: RedPajamaCommonCrawl


This security recorder or body camera is an excellent Video & Audio recording device for Law Enforcement, Military, Security Personnel or anyone needing to record evidential video and audio, it can be worn on the shoulder lapel, breast pocket or somewhere similar, this body camera only takes one button press to turn on the unit and it will automatically start recording clear video and audio, when recording at night time the unit features built-in night vision infrared LED's that allow recording in total darkness. This security recorder will record full colour video at D1 resolution, 720x480@30fps, it can also take jpg stills. There is an LCD screen for video playback and jpg still picture examination, audio can be heard via the built-in speaker. All video, audio and jpg images are stored on the TF card.
PGP (Pretty Good Privacy) device?can add encryption to prevent information being stolen.
Intercom function, waterproof function, shock resistant, compact size.
Supports TF Card to 16GB.
Video & Audio Recording at D1 resolution, 720x480@30fps, 1280x720.
Take photos and save on TF card.
1.5� TFT LCD Screen for easy video playback and picture examination.
USB port to make it easy to examine video and photos on computer.
Date & time stamp to ensure the effectiveness of the evidence.
8 IR LEDs for image capture at night.
Build in rechargeable Li-battery, 3.7v 800mA, 4hrs continuous working.


text:
INSIDE THE MEGA TWISTER
EXCLUSIVE GALLERIES
Behind the Disaster
Take a further look into twisters and what causes them.
The tornado that struck El Reno, Oklahoma, on May 31, 2013, defined superlatives. It was the largest, one of the fastest, and—for storm chasers—the most lethal twister ever recorded on Earth. Among those it claimed was Tim Samaras, revered as one of the most experienced and cautious scientists studying tornadoes. But this storm was unlike any he had witnessed before. In this National Geographic Special, we unravel the tornado and tell its story. But this is not your typical storm chasing documentary. While this film will include many firsthand accounts and harrowing videos from scientists and amateurs in pursuit of the tornado, it was also probably the best documented storm in history and these clips are part of a unique and ever-growing database documenting every terrifying twist and turn of the storm from all angles.
Compiling this archive is National Geographic grantee Dr....
Inside the Mega Twister on Facebook
Get news on your profile
Find more here!
It's a season of change and surprises, with one of the closest battles in "Wicked Tuna" history, that culminates in a dramatic nail-biting final episode.
Big Cat Week
Nat Geo WILD presents the sixth annual BIG CAT WEEK to shine a light on the world's most majestic big cat species and their struggle to survive.
Story of God With Morgan Freeman
This is the ultimate quest to uncover the meaning of life.
Go on the hunt to determine which aspects of your personality reveal the Big Cat that roars from within.
More On Disaster
Air Crash Investigation: National Geographic Channel
Situation Critical: National Geographic Channel
Salvage Code Red: National Geographic Channel
World War Two: The Apocalypse: National Geographic Channel


"Rather than consider the Mayor's proposal as the only solution to the diversity problem, leaders in the Senate and Assembly have the power to bring back accelerated programs we've phased out, like IGC (Intellectually Gifted Children), SP (Special Progress), and Honors programs. Everyone deserves the same opportunity I had, it's about time we expand the Specialized High Schools and create more pathways to high achieving schools, while integrating from a much earlier age," said Tahseen Chowdhury, Former Stuyvesant High School Student Union President.
"As an educator, my Dad realized the disparities in school funding from one school to another. I remember being placed in IGC (Intellectually Gifted Children) & SP (Special Progress) classes as a child, and our incredibly diverse classrooms of black and brown children would work hard to stay in that group until the final report card in June," said Dr. Ivan Khan, CEO & President of Khan's Tutorial.
New York State Senator John Liu who is also Chairman of New York City Education Committee organized the event to engage the community and ensure that all stakeholders had a chance to provide their input. Senator Liu has argued that Mayor de Blasio's plan to scrap the SHSAT is racist in that the mayor did not consult with the Asian community and failed to consider their needs before rolling out the proposal.
"This is necessary because last year [City Hall] proposed a plan without including many parts of the city," Senator Liu said. "This has turned into a racial issue because of the way City Hall has framed the issue to begin with."
With 11 locations in the outer boroughs of New York City, Brooklyn, the Bronx, and in the Jackson Heights, Jamaica, Astoria, Sunnyside, Ozone Park, and Floral Park neighborhoods of Queens, Khan's Tutorial primarily serves in assisting families in low-income, new immigrant neighborhoods. Over 3,362 students have gained admission to New York City's Specialized High Schools through Khan's Tutorial since its inception in 1994.


Naspers-backed PayU Payments Pvt. Ltd has seen another top level exit with the resignation of its finance head. Gurpreet Singh, vice president and head of finance at PayU India, has quit the digital payments firm to join HCL Technologies.
While confirming the development to Techcircle.in, Singh said he will be a part of HCL Technologies' leadership team.
Singh—who was a part of PayU's finance leadership team and was responsible for formulating business strategy and vision, financial budgets, and managing investors' expectations—didn't give more details about his role at HCL. It is still "evolving", he said.
His last working day at PayU was October 14.
Recently, PayU and Citrus Pay merged in a $130 million deal. As part of the deal, the combined entity also witnessed management restructuring under which PayU co-founder and chief executive Nitin Gupta had decided to leave the firm. Citrus Pay's managing director Amrish Rau took over as chief executive of the merged entity while its founder Jitendra Gupta joined as managing director.
"The shift has nothing to do with the merger and consolidation and is more to do with my personal interest of switching from a finance leadership role to a business strategy role," Singh said.
Earlier this week, Abhishek Tripathi, associate director and business head at PayU, announced his decision to quit the company to lead the SMB (small and medium-sized business) vertical of Airtel Payments Bank.
In July, PayU's digital marketing head Saranjeet Singh joined Airtel Payments Bank (formerly known as Airtel M-Commerce Services Ltd) in the similar role.
Airtel Payments Bank is one of the 11 entities which got the Reserve Bank of India (RBI)'s in-principle nod to offer payment banking services.
The firm, which has presence in more than 800 towns across India, has been firming up its plans to roll out its banking network.
Airtel Airtel Payments Bank Citrus Pay Gurpreet Singh HCL Technologies Naspers PayU PayU Payments Pvt. Ltd.


With satellites gathering more data every year and at higher resolutions, SAC saw its data acquisition rates double which highlighted a need for a more scalable and affordable storage solution.
Satellite Applications Catapult (SAC) has replaced its legacy NAS with Cloudian's HyperStore object storage system and HyperFile NAS controller.
Harwell-based SAC helps organisations make use of and benefit from satellite technologies. It was established in 2013 by Innovate UK (formerly the Technology Strategy Board) as part of a network of emerging technology centres to help drive economic growth.
With future predicated data acquisition rates expecting to double from 5PB of unstructured data to an estimated 10PB per year, SAC needed a new solution to deal with its sprawling and costly NAS deviceestate. It initially installed four Cloudian appliances which, it's claimed, saved almost 75 per cent on data centre footprint by reducing the rack space needed for this capacity from 60U to just 16U.
The vendor says the move also gave SAC "limitless" scalability to cope with future storage growth. It says HyperStoreallowsthe company to expand its storage as needed by adding nodes that are automatically incorporated into its storage pool. According to Cloudian, the HyperFileNAS controller deployed with HyperStoreprovides the functionality of traditional enterprise NAS, including seamless connectivity with Windows- and Linux-based applications.
Furthermore, SAC's support costs are said to have come down by 40 per cent, while savings on power and cooling alone have nearly offset the cost of the new storage hardware.
This latest deployment for Cloudian follows on from its recent acquisition of Infinity Storage announced earlier this year (see News, Mar 2018).


text:
<?php

namespace RFM\Api;

use RFM\Facade\Input;
use RFM\Facade\Log;
use RFM\Repository\Local\ItemModel;

class LocalApi implements ApiInterface
{
    /**
     * @var \RFM\Repository\Local\Storage
     */
    protected $storage;

    /**
     * Api constructor.
     */
    public function __construct()
    {
        $this->storage = app()->getStorage('local');
    }

    /**
     * @inheritdoc
     */
    public function actionInitiate()
    {
        // config options that affect the client-side
        $shared_config = [
            'security' => [
                'readOnly' => $this->storage->config('security.readOnly'),
                'extensions' => [
                    'policy' => $this->storage->config('security.extensions.policy'),
                    'ignoreCase' => $this->storage->config('security.extensions.ignoreCase'),
                    'restrictions' => $this->storage->config('security.extensions.restrictions'),
                ],
            ],
            'upload' => [
                'fileSizeLimit' => $this->storage->config('upload.fileSizeLimit'),
            ],
        ];

        return [
            'id' => '/',
            'type' => 'initiate',
            'attributes' => [
                'config' => $shared_config,
            ],
        ];
    }

    /**
     * @inheritdoc
     */
    public function actionGetFolder()
    {
        $files_list = [];
        $response_data = [];
        $model = new ItemModel(Input::get('path'));
        Log::info('opening folder "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkReadPermission();
        $model->checkRestrictions();

        if (!$model->isDir) {
            app()->error('DIRECTORY_NOT_EXIST', [$model->pathRelative]);
        }

        if (!$handle = @opendir($model->pathAbsolute)) {
            app()->error('UNABLE_TO_OPEN_DIRECTORY', [$model->pathRelative]);
        } else {
            while (false !== ($file = readdir($handle))) {
                if ($file != "." && $file != "..") {
                    array_push($files_list, $file);
                }
            }
            closedir($handle);

            foreach ($files_list as $file) {
                $file_path = $model->pathRelative . $file;
                if (is_dir($model->pathAbsolute . $file)) {
                    $file_path .= '/';
                }

                $item = new ItemModel($file_path);
                if ($item->isUnrestricted()) {
                    $response_data[] = $item->getInfo();
                }
            }
        }

        return $response_data;
    }

    /**
     * @inheritdoc
     */
    public function actionGetFile()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('opening file "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkReadPermission();
        $model->checkRestrictions();

        if ($model->isDir) {
            app()->error('FORBIDDEN_ACTION_DIR');
        }

        return $model->getInfo();
    }

    /**
     * @inheritdoc
     */
    public function actionUpload()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('uploading to "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkWritePermission();

        $content = $this->storage->initUploader($model)->post(false);

        $response_data = [];
        $files = isset($content['files']) ? $content['files'] : null;
        // there is only one file in the array as long as "singleFileUploads" is set to "true"
        if ($files && is_array($files) && is_object($files[0])) {
            $file = $files[0];
            if (isset($file->error)) {
                $error = is_array($file->error) ? $file->error : [$file->error];
                app()->error($error[0], isset($error[1]) ? $error[1] : []);
            } else {
                $uploadedPath = $this->storage->cleanPath('/' . $model->pathRelative . '/' . $file->name);
                $modelUploaded = new ItemModel($uploadedPath);
                $response_data[] = $modelUploaded->getInfo();
            }
        } else {
            app()->error('ERROR_UPLOADING_FILE');
        }

        return $response_data;
    }

    /**
     * @inheritdoc
     */
    public function actionAddFolder()
    {
        $targetPath = Input::get('path');
        $targetName = Input::get('name');

        $modelTarget = new ItemModel($targetPath);
        $modelTarget->checkPath();
        $modelTarget->checkWritePermission();

        $dirName = $this->storage->normalizeString(trim($targetName, '/')) . '/';
        $relativePath = $this->storage->cleanPath('/' . $targetPath . '/' . $dirName);

        $model = new ItemModel($relativePath);
        Log::info('adding folder "' . $model->pathAbsolute . '"');

        $model->checkRestrictions();

        if ($model->isExists && $model->isDir) {
            app()->error('DIRECTORY_ALREADY_EXISTS', [$targetName]);
        }

        if (!mkdir($model->pathAbsolute, 0755)) {
            app()->error('UNABLE_TO_CREATE_DIRECTORY', [$targetName]);
        }

        return $model->getInfo();
    }

    /**
     * @inheritdoc
     */
    public function actionRename()
    {
        $modelOld = new ItemModel(Input::get('old'));
        $suffix = $modelOld->isDir ? '/' : '';
        $filename = Input::get('new');

        // forbid to change path during rename
        if (strrpos($filename, '/') !== false) {
            app()->error('FORBIDDEN_CHAR_SLASH');
        }

        // check if not requesting root storage folder
        if ($modelOld->isDir && $modelOld->isRoot()) {
            app()->error('NOT_ALLOWED');
        }

        $modelNew = new ItemModel($modelOld->closest()->pathRelative . $filename . $suffix);
        Log::info('moving "' . $modelOld->pathAbsolute . '" to "' . $modelNew->pathAbsolute . '"');

        $modelOld->checkPath();
        $modelOld->checkWritePermission();
        $modelOld->checkRestrictions();
        $modelNew->checkRestrictions();

        // define thumbnails models
        $modelThumbOld = $modelOld->thumbnail();
        $modelThumbNew = $modelNew->thumbnail();

        // check thumbnail file or thumbnails folder permissions
        if ($modelThumbOld->isExists) {
            $modelThumbOld->checkWritePermission();
        }

        if ($modelNew->isExists) {
            if ($modelNew->isDir) {
                app()->error('DIRECTORY_ALREADY_EXISTS', [$modelNew->pathRelative]);
            } else {
                app()->error('FILE_ALREADY_EXISTS', [$modelNew->pathRelative]);
            }
        }

        // rename file or folder
        if (rename($modelOld->pathAbsolute, $modelNew->pathAbsolute)) {
            Log::info('renamed "' . $modelOld->pathAbsolute . '" to "' . $modelNew->pathAbsolute . '"');

            // rename thumbnail file or thumbnails folder if exists
            if ($modelThumbOld->isExists) {
                rename($modelThumbOld->pathAbsolute, $modelThumbNew->pathAbsolute);
            }
        } else {
            if ($modelOld->isDir) {
                app()->error('ERROR_RENAMING_DIRECTORY', [$modelOld->pathRelative, $modelNew->pathRelative]);
            } else {
                app()->error('ERROR_RENAMING_FILE', [$modelOld->pathRelative, $modelNew->pathRelative]);
            }
        }

        return $modelNew->getInfo();
    }

    /**
     * @inheritdoc
     */
    public function actionCopy()
    {
        $modelSource = new ItemModel(Input::get('source'));
        $modelTarget = new ItemModel(Input::get('target'));

        $suffix = $modelSource->isDir ? '/' : '';
        $basename = basename($modelSource->pathAbsolute);
        $modelNew = new ItemModel($modelTarget->pathRelative . $basename . $suffix);
        Log::info('copying "' . $modelSource->pathAbsolute . '" to "' . $modelNew->pathAbsolute . '"');

        if (!$modelTarget->isDir) {
            app()->error('DIRECTORY_NOT_EXIST', [$modelTarget->pathRelative]);
        }

        // check if not requesting root storage folder
        if ($modelSource->isDir && $modelSource->isRoot()) {
            app()->error('NOT_ALLOWED');
        }

        // check items permissions
        $modelSource->checkPath();
        $modelSource->checkReadPermission();
        $modelSource->checkRestrictions();
        $modelTarget->checkPath();
        $modelTarget->checkWritePermission();
        $modelNew->checkRestrictions();

        // check if file already exists
        if ($modelNew->isExists) {
            if ($modelNew->isDir) {
                app()->error('DIRECTORY_ALREADY_EXISTS', [$modelNew->pathRelative]);
            } else {
                app()->error('FILE_ALREADY_EXISTS', [$modelNew->pathRelative]);
            }
        }

        // define thumbnails models
        $modelThumbOld = $modelSource->thumbnail();
        $modelThumbNew = $modelNew->thumbnail();

        // check thumbnail file or thumbnails folder permissions
        if ($modelThumbOld->isExists) {
            $modelThumbOld->checkReadPermission();
            if ($modelThumbNew->closest()->isExists) {
                $modelThumbNew->closest()->checkWritePermission();
            }
        }

        // copy file or folder
        if($this->storage->copyRecursive($modelSource->pathAbsolute, $modelNew->pathAbsolute)) {
            Log::info('copied "' . $modelSource->pathAbsolute . '" to "' . $modelNew->pathAbsolute . '"');

            // copy thumbnail file or thumbnails folder
            if ($modelThumbOld->isExists) {
                if ($modelThumbNew->closest()->isExists) {
                    $this->storage->copyRecursive($modelThumbOld->pathAbsolute, $modelThumbNew->pathAbsolute);
                }
            }
        } else {
            if ($modelSource->isDir) {
                app()->error('ERROR_COPYING_DIRECTORY', [$basename, $modelTarget->pathRelative]);
            } else {
                app()->error('ERROR_COPYING_FILE', [$basename, $modelTarget->pathRelative]);
            }
        }

        return $modelNew->getInfo();
    }

    /**
     * @inheritdoc
     */
    public function actionMove()
    {
        $modelSource = new ItemModel(Input::get('old'));
        $modelTarget = new ItemModel(Input::get('new'));

        $suffix = $modelSource->isDir ? '/' : '';
        $basename = basename($modelSource->pathAbsolute);
        $modelNew = new ItemModel($modelTarget->pathRelative . $basename . $suffix);
        Log::info('moving "' . $modelSource->pathAbsolute . '" to "' . $modelNew->pathAbsolute . '"');

        if (!$modelTarget->isDir) {
            app()->error('DIRECTORY_NOT_EXIST', [$modelTarget->pathRelative]);
        }

        // check if not requesting root storage folder
        if ($modelSource->isDir && $modelSource->isRoot()) {
            app()->error('NOT_ALLOWED');
        }

        // check items permissions
        $modelSource->checkPath();
        $modelSource->checkWritePermission();
        $modelSource->checkRestrictions();
        $modelTarget->checkPath();
        $modelTarget->checkWritePermission();
        $modelNew->checkRestrictions();

        // check if file already exists
        if ($modelNew->isExists) {
            if ($modelNew->isDir) {
                app()->error('DIRECTORY_ALREADY_EXISTS', [$modelNew->pathRelative]);
            } else {
                app()->error('FILE_ALREADY_EXISTS', [$modelNew->pathRelative]);
            }
        }

        // define thumbnails models
        $modelThumbOld = $modelSource->thumbnail();
        $modelThumbNew = $modelNew->thumbnail();

        // check thumbnail file or thumbnails folder permissions
        if ($modelThumbOld->isExists) {
            $modelThumbOld->checkWritePermission();
            if ($modelThumbNew->closest()->isExists) {
                $modelThumbNew->closest()->checkWritePermission();
            }
        }

        // move file or folder
        if (rename($modelSource->pathAbsolute, $modelNew->pathAbsolute)) {
            Log::info('moved "' . $modelSource->pathAbsolute . '" to "' . $modelNew->pathAbsolute . '"');

            // move thumbnail file or thumbnails folder if exists
            if ($modelThumbOld->isExists) {
                // do if target paths exists, otherwise remove old thumbnail(s)
                if ($modelThumbNew->closest()->isExists) {
                    rename($modelThumbOld->pathAbsolute, $modelThumbNew->pathAbsolute);
                } else {
                    $modelThumbOld->remove();
                }
            }
        } else {
            if ($modelSource->isDir) {
                app()->error('ERROR_MOVING_DIRECTORY', [$basename, $modelTarget->pathRelative]);
            } else {
                app()->error('ERROR_MOVING_FILE', [$basename, $modelTarget->pathRelative]);
            }
        }

        return $modelNew->getInfo();
    }

    /**
     * @inheritdoc
     */
    public function actionEditFile()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('opening file "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkReadPermission();
        $model->checkRestrictions();

        if($model->isDir) {
            app()->error('FORBIDDEN_ACTION_DIR');
        }

        $content = file_get_contents($model->pathAbsolute);

        if($content === false) {
            app()->error('ERROR_OPENING_FILE');
        }

        $item = $model->getInfo();
        $item['attributes']['content'] = $content;
        return $item;
    }

    /**
     * @inheritdoc
     */
    public function actionSaveFile()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('saving file "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkWritePermission();
        $model->checkRestrictions();

        if($model->isDir) {
            app()->error('FORBIDDEN_ACTION_DIR');
        }

        $result = file_put_contents($model->pathAbsolute, Input::get('content'), LOCK_EX);

        if(!is_numeric($result)) {
            app()->error('ERROR_SAVING_FILE');
        }

        Log::info('saved "' . $model->pathAbsolute . '"');

        // get updated file info after save
        clearstatcache();
        return $model->getInfo();
    }

    /**
     * Seekable stream: http://stackoverflow.com/a/23046071/1789808
     * @inheritdoc
     */
    public function actionReadFile()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('reading file "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkReadPermission();
        $model->checkRestrictions();

        if($model->isDir) {
            app()->error('FORBIDDEN_ACTION_DIR');
        }

        $filesize = filesize($model->pathAbsolute);
        $length = $filesize;
        $offset = 0;

        if(isset($_SERVER['HTTP_RANGE'])) {
            if(!preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'], $matches)) {
                header('HTTP/1.1 416 Requested Range Not Satisfiable');
                header('Content-Range: bytes */' . $filesize);
                exit;
            }

            $offset = intval($matches[1]);

            if(isset($matches[2])) {
                $end = intval($matches[2]);
                if($offset > $end) {
                    header('HTTP/1.1 416 Requested Range Not Satisfiable');
                    header('Content-Range: bytes */' . $filesize);
                    exit;
                }
                $length = $end - $offset;
            } else {
                $length = $filesize - $offset;
            }

            $bytes_start = $offset;
            $bytes_end = $offset + $length - 1;

            header('HTTP/1.1 206 Partial Content');
            // A full-length file will indeed be "bytes 0-x/x+1", think of 0-indexed array counts
            header('Content-Range: bytes ' . $bytes_start . '-' . $bytes_end . '/' . $filesize);
            // While playing media by direct link (not via FM) FireFox and IE doesn't allow seeking (rewind) it in player
            // This header can fix this behavior if to put it out of this condition, but it breaks PDF preview
            header('Accept-Ranges: bytes');
        }

        header('Content-Type: ' . mime_content_type($model->pathAbsolute));
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . $length);
        header('Content-Disposition: inline; filename="' . basename($model->pathAbsolute) . '"');

        $fp = fopen($model->pathAbsolute, 'r');
        fseek($fp, $offset);
        $position = 0;

        while($position < $length) {
            $chunk = min($length - $position, 1024 * 8);

            echo fread($fp, $chunk);
            flush();
            ob_flush();

            $position += $chunk;
        }
        exit;
    }

    /**
     * @inheritdoc
     */
    public function actionGetImage($thumbnail)
    {
        $modelImage = new ItemModel(Input::get('path'));
        Log::info('loading image "' . $modelImage->pathAbsolute . '"');

        if ($modelImage->isDir) {
            app()->error('FORBIDDEN_ACTION_DIR');
        }

        // if $thumbnail is set to true we return the thumbnail
        if ($thumbnail === true && $this->storage->config('images.thumbnail.enabled')) {
            // create thumbnail model
            $model = $modelImage->thumbnail();

            // generate thumbnail if it doesn't exist or caching is disabled
            if (!$model->isExists || $this->storage->config('images.thumbnail.cache') === false) {
                $modelImage->createThumbnail();
            }
        } else {
            $model = $modelImage;
        }

        $model->checkReadPermission();
        $model->checkRestrictions();

        Log::info('loaded image "' . $model->pathAbsolute . '"');

        header("Content-Type: image/octet-stream");
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . $this->storage->getRealFileSize($model->pathAbsolute));
        header('Content-Disposition: inline; filename="' . basename($model->pathAbsolute) . '"');

        readfile($model->pathAbsolute);
        exit;
    }

    /**
     * @inheritdoc
     */
    public function actionDelete()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('deleting "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkWritePermission();
        $model->checkRestrictions();

        // check if not requesting root storage folder
        if ($model->isDir && $model->isRoot()) {
            app()->error('NOT_ALLOWED');
        }

        $info = $model->getInfo();
        $modelThumb = $model->thumbnail();

        if ($model->isDir) {
            $this->storage->unlinkRecursive($model->pathAbsolute);
            Log::info('deleted "' . $model->pathAbsolute . '"');

            // delete thumbnail if exists
            if ($modelThumb->isExists) {
                $this->storage->unlinkRecursive($modelThumb->pathAbsolute);
            }
        } else {
            unlink($model->pathAbsolute);
            Log::info('deleted "' . $model->pathAbsolute . '"');

            // delete thumbnails if exists
            if ($modelThumb->isExists) {
                unlink($modelThumb->pathAbsolute);
            }
        }

        return $info;
    }

    /**
     * @inheritdoc
     */
    public function actionDownload()
    {
        $model = new ItemModel(Input::get('path'));
        Log::info('downloading "' . $model->pathAbsolute . '"');

        $model->checkPath();
        $model->checkReadPermission();
        $model->checkRestrictions();

        // check if not requesting root storage folder
        // TODO: This restriction seems arbitration, it could be useful for business clients
        if ($model->isDir && $model->isRoot()) {
            app()->error('NOT_ALLOWED');
        }

        if (request()->isXmlHttpRequest()) {
            return $model->getInfo();
        } else {
            $targetPath = $model->pathAbsolute;

            if ($model->isDir) {
                $destinationPath = sys_get_temp_dir() . '/' . basename($model->pathAbsolute) . '.zip';

                // if Zip archive is created
                if ($this->storage->zipFile($targetPath, $destinationPath, true)) {
                    $targetPath = $destinationPath;
                } else {
                    app()->error('ERROR_CREATING_ZIP');
                }
            }
            $fileSize = $this->storage->getRealFileSize($targetPath);

            header('Content-Description: File Transfer');
            header('Content-Type: ' . mime_content_type($targetPath));
            header('Content-Disposition: attachment; filename="' . basename($targetPath) . '"');
            header('Content-Transfer-Encoding: binary');
            header('Content-Length: ' . $fileSize);
            // handle caching
            header('Pragma: public');
            header('Expires: 0');
            header('Cache-Control: must-revalidate, post-check=0, pre-check=0');

            // read file by chunks to handle large files
            // if you face an issue while downloading large files yet, try the following solution:
            // https://github.com/servocoder/RichFilemanager/issues/78

            $chunkSize = 5 * 1024 * 1024;
            if ($chunkSize && $fileSize > $chunkSize) {
                $handle = fopen($targetPath, 'rb');
                while (!feof($handle)) {
                    echo fread($handle, $chunkSize);
                    @ob_flush();
                    @flush();
                }
                fclose($handle);
            } else {
                readfile($targetPath);
            }

            Log::info('downloaded "' . $targetPath . '"');
            exit;
        }
    }

    /**
     * @inheritdoc
     */
    public function actionSummarize()
    {
        $path = '/';
        $attributes = [
            'size' => 0,
            'files' => 0,
            'folders' => 0,
            'sizeLimit' => $this->storage->config('options.fileRootSizeLimit'),
        ];

        try {
            $this->storage->getDirSummary($path, $attributes);
        } catch (\Exception $e) {
            app()->error('ERROR_SERVER');
        }

        return [
            'id' => $path,
            'type' => 'summary',
            'attributes' => $attributes,
        ];
    }

    /**
     * @inheritdoc
     */
    public function actionExtract()
    {
        if (!extension_loaded('zip')) {
            app()->error('NOT_FOUND_SYSTEM_MODULE', ['zip']);
        }

        $modelSource = new ItemModel(Input::get('source'));
        $modelTarget = new ItemModel(Input::get('target'));
        Log::info('extracting "' . $modelSource->pathAbsolute . '" to "' . $modelTarget->pathAbsolute . '"');

        $modelSource->checkPath();
        $modelTarget->checkPath();
        $modelSource->checkReadPermission();
        $modelTarget->checkWritePermission();
        $modelSource->checkRestrictions();
        $modelTarget->checkRestrictions();

        if ($modelSource->isDir) {
            app()->error('FORBIDDEN_ACTION_DIR');
        }

        $zip = new \ZipArchive();
        if ($zip->open($modelSource->pathAbsolute) !== true) {
            app()->error('ERROR_EXTRACTING_FILE');
        }

        /**
         * @var $rootLevelItems ItemModel[]
         */
        $rootLevelItems = [];
        $responseData = [];

        // make all the folders
        for ($i = 0; $i < $zip->numFiles; $i++) {
            $filename = $zip->getNameIndex($i);
            $model = new ItemModel($modelTarget->pathRelative . $filename);

            if ($filename[strlen($filename) - 1] === "/" && $model->isUnrestricted()) {
                $created = mkdir($model->pathAbsolute, 0700, true);

                if ($created) {
                    // extract root-level folders from archive manually
                    $rootName = substr($filename, 0, strpos($filename, '/') + 1);
                    if (!array_key_exists($rootName, $rootLevelItems)) {
                        $rootModel = ($rootName === $filename) ? $model : new ItemModel($modelTarget->pathRelative . $rootName);
                        $rootLevelItems[$rootName] = $rootModel;
                    }
                }
            }
        }

        // unzip into the folders
        for ($i = 0; $i < $zip->numFiles; $i++) {
            $filename = $zip->getNameIndex($i);
            $model = new ItemModel($modelTarget->pathRelative . $filename);

            if ($filename[strlen($filename) - 1] !== "/" && $model->isUnrestricted()) {
                $copied = copy('zip://' . $modelSource->pathAbsolute . '#' . $filename, $model->pathAbsolute);

                if ($copied && strpos($filename, '/') === false) {
                    $rootLevelItems[] = $model;
                }
            }
        }

        $zip->close();

        foreach ($rootLevelItems as $model) {
            $responseData[] = $model->getInfo();
        }

        return $responseData;
    }
}

redpajama_set_name: RedPajamaGithub


"The Music They Made," a short video made by Wm. Ferguson and featured in the New York Times – watch for the unusual photographs that you may not have seen before of these wonderful musicans who died this year.
It's interesting to me that I recognized all of the songs, but didn't always have a visual of the musician. I liked experiencing through this video the power of photography to enhance my experience, and make it more personal when hearing each one's music.
What a great example of how simplicity of presentation can also still be powerful.
I miss many of them – Gil Scott Heron and Todd Rungren were unique – the photo of Todd Rungren is great, complex – and the hearing/seeing all brought back memories of happy times.
A nice tribute to a diversity of individuals, contributions to the world, and lasting legacies.
P.S. I like this term – a "sound collage" (used by Mr. Ferguson).
Todd Rundgren is not dead- at least at the moment I am writing this. It was his keyboardist, Mark "Moogy" Klingman, who died.
Thanks so much for your comment – wow, didn't want to wish Todd dead and had wondered how I missed that announcement!
Thanks for paying attention – I stand corrected.


Axel Audio recently launched a Kickstarter campaign for their stylish, modular headphones that revolutionizes the way music lovers everywhere enjoy their music.
The outside of the headphones are super stylish however it's what's on the inside that counts. The inner workings of these Axel headphones with Soundscape Pure are specially engineered to your listening preference with Soundscape. You basically choose how you like to listen to your music when designing your headphones and they deliver!
Axel's headphones have fully interchangeable modular components. Axel aims to simplify the normally daunting headphone-buying process by offering a menu of components from which the customer selects to create their ideal headphones. The menu includes a choice of 3 specifically engineered speaker units, dubbed Soundscapes (Core, Pure, and Deep) and 3 styles of headband inserts (Classic, Waves, or Spikes). The headphones are available with both on-ear speaker units and over-ear speaker units. The on-ear models will be available in either black or white, while the over-ear models will initially be available in black only.
"As a very general overview, Soundscape Pure was designed with the 'audio purist' in mind, to create an intimate and detailed listening experience. Soundscape Deep is for the 'bass heads' with reverberating lows and full yet controlled power. Soundscape Core may be the most versatile, with smooth textures and a sweet mid-range. It's great for rock," CEO and Co-Founder of Axel Audio, Kevin Oh states.
So far the Kickstarter campaign has raised over $66k at the time of this writing and seeks to raise 180k before production.
I know most of you take your music listening just as serious as I do so make your way over to Kickstarter to get your hands on some of these innovative Axel headphones!


Posted by eraneven on March 21, 2011 · Comments Off on What is Pre-Birth Acupuncture?
Pre-birth acupuncture is recommended for woman from week 36 onwards and weekly thereafter. Weekly acupuncture promotes a healthy and natural birth, by boosting energy, softening the ligaments and tendons prior to labour and aiding in cervical dilation. It also promotes relaxation and nourishes the blood in the body (which helps you to sleep better, have more energy, and a greater sense of wellbeing). Midwives who have attended births where their patient had pre-birth acupuncture, noted that the length of labour was reduced, the need for medical interventions were reduced (less medical induction, epidural and caesarean births), and saw an increase in normal vaginal deliveries, which is optimal for the health of the baby and mother.


Compare and filter Chromebooks by specs such as the processor, RAM, Storage, Battery Life, Screen size, Resolution and more. This guide will help you find the most powerful laptop within your budget. The ultimate collection of ASUS Chromebooks – 2019 Guide.
The Best Chromebook For You. This Chromebook comparison buying chart aims to help you decide which model is best for your needs. Below, we go into detail describing each component of a Chromebook so you may have a better understanding of what is more important to you.
The processor is definitely the most important hardware on the Chromebook. With a powerful processor, the Chromebook will be able to operate very quickly. Cheaper and less powerful processors will struggle to handle heavy usage. Although the processor is one of the most expensive components of a Chromebook, a weak processor can make or break the product.
Processors usually come in two flavors, Intel or ARM. Neither brand has much of an advantage over the other but that can change from time to time when newer processors are released.
A processors speed is measured in Gigahertz (GHz), the higher the better. However, a high speed alone will not ensure the processor will perform smoothly. Processors also have multiple cores which help run simultaneous applications much quicker than a single core. Most Chromebooks today come equipped with processors using dual-core or quad-core.
The battery life indicates how long the Chromebook can stay running with moderate usage. With a long-lasting battery, you can use the device for extended periods of time without needed to recharge. Most Chromebook battery life slightly varies from about 9 – 13 hours. Battery life also varies depending on the type of activities done with the Chromebook. Over a long period of time, typically years, battery begin to degrade and lose it's ability to hard its charge for long. You may start to see the battery life start to drop slightly faster.
The storage of a Chromebook is used to save files, photos, music, documents, and anything else. Storage drives are typically measured in size by the number of gigabytes they can hold. The higher the gigabytes (GB) the better.
Storage drives can be manufactured in different types. It is important to identify what type of storage your Chromebook or laptop is using. The two primary types of drives are Solid State Drives (SSD) or Hard Disk Drives (HDD).
HDD is built with older technology and can typically hold more data than an SSD. However, an HDD is slower to read and write data. The major benefit of using an HDD today is for its large storage capacity. Prior to the existence of SSD, HDD was the medium for the installation of Operating Systems (OS). Because of the slow speed of HDD, it is no longer ideal to install OS on an HDD anymore.
SSD is a fairly new technology with speeds faster than an HDD can normally achieve. Most Chromebook's today use SSD to run Chrome OS in favor of HDD for multiple reasons. Solid State Drives are faster than Hard Disk. They are also lighter since they are built with fewer mechanical parts. They are smaller in size which allows Chromebooks to be very thin and easy to carry.
Random Access Memory (RAM) is used when Chrome OS and it's applications are running. Think of RAM as a giant basic of temporary data that applications need to quickly use to fulfill its requirements. With more RAM, you can use more applications simultaneously, allowing you to multi-task more effectively. The amount of memory that can be used in RAM is measured in gigabytes. Although the primary technical detail for RAM is its size, it is also important to look at the speed of the RAM. When RAM is used, the RAM will take time to give that data to the application or operating system. This speed is measured in hertz (Hz) or megahertz (MHz).


text:
package org.wso2.andes.thrift;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
import org.apache.thrift.transport.TTransportException;
import org.wso2.andes.configuration.AndesConfigurationManager;
import org.wso2.andes.configuration.enums.AndesConfiguration;
import org.wso2.andes.server.cluster.coordination.hazelcast.HazelcastAgent;
import org.wso2.andes.kernel.slot.ConnectionException;
import org.wso2.andes.kernel.slot.Slot;
import org.wso2.andes.kernel.slot.SlotCoordinationConstants;
import org.wso2.andes.kernel.slot.SlotDeliveryWorkerManager;
import org.wso2.andes.thrift.slot.gen.SlotInfo;
import org.wso2.andes.thrift.slot.gen.SlotManagementService;

/**
 * A wrapper client for the native thrift client. All the public methods in this class are
 * synchronized in order to avoid out of sequence response exception from thrift server. Only one
 * method should be triggered at a time in order to get the responses from the server in order.
 */

public class MBThriftClient {

    /**
     * A state variable to indicate whether the reconnecting  to the thrift server is started or
     * not
     */
    private static boolean reconnectingStarted = false;

    private static TTransport transport;

    private static SlotManagementService.Client client = null;

    private static final Log log = LogFactory.getLog(MBThriftClient.class);

    /**
     * getSlot method. Returns Slot Object, when the
     * queue name is given
     *
     * @param queueName name of the queue
     * @param nodeId    of this node
     * @return slot object
     * @throws ConnectionException
     */
    public static synchronized Slot getSlot(String queueName,
                                            String nodeId) throws ConnectionException {
        SlotInfo slotInfo;
        try {
            client = getServiceClient();
            slotInfo = client.getSlotInfo(queueName, nodeId);
            return convertSlotInforToSlot(slotInfo);
        } catch (TException e) {
            try {
                //retry once
                reConnectToServer();
                slotInfo = client.getSlotInfo(queueName, nodeId);
                return convertSlotInforToSlot(slotInfo);
            } catch (TException e1) {
                handleCoordinatorChanges();
                throw new ConnectionException("Coordinator has changed", e);
            }

        }
    }

    /**
     * Convert SlotInfo object to Slot object
     *
     * @param slotInfo object generated by thrift
     * @return slot object
     */
    private static Slot convertSlotInforToSlot(SlotInfo slotInfo) {
        Slot slot = new Slot();
        slot.setStartMessageId(slotInfo.getStartMessageId());
        slot.setEndMessageId(slotInfo.getEndMessageId());
        slot.setStorageQueueName(slotInfo.getQueueName());
        return slot;
    }

    /**
     * updateMessageId method. This method will pass the locally chosen slot range to the SlotManagerClusterMode. Slot manager
     * maintains a list of slot ranges in a map along with the queue. This messageId will
     * be stored in that map.
     *
     * @param queueName name of the queue
     * @param nodeId unique hazelcast identifier of node.
     * @param startMessageId start message Id of the locally chosen slot.
     * @param endMessageId end message Id of the locally chosen slot.
     * @throws TException in case of an connection error
     */
    public static synchronized void updateMessageId(String queueName, String nodeId,
                                                    long startMessageId, long endMessageId) throws ConnectionException {
        try {
            client = getServiceClient();
            client.updateMessageId(queueName, nodeId, startMessageId, endMessageId);
        } catch (TException e) {
            try {
                //retry once
                reConnectToServer();
                client.updateMessageId(queueName, nodeId, startMessageId, endMessageId);
            } catch (TException e1) {
                handleCoordinatorChanges();
                throw new ConnectionException("Coordinator has changed", e);
            }

        }
    }

    /**
     * Delete the slot from SlotAssignmentMap when all the messages in the slot has been sent and
     * all the acks are received.
     *
     * @param queueName  name of the queue where slot belongs to
     * @param slot      to be deleted
     * @throws TException
     */
    public static synchronized boolean deleteSlot(String queueName, Slot slot,
                                               String nodeId) throws ConnectionException {
        SlotInfo slotInfo = new SlotInfo(slot.getStartMessageId(), slot.getEndMessageId(),
                slot.getStorageQueueName(),nodeId,slot.isAnOverlappingSlot());
        boolean deleteSuccess = false;
        try {
            client = getServiceClient();
            deleteSuccess = client.deleteSlot(queueName, slotInfo, nodeId);
        } catch (TException e) {
            try {
                //retry to connect once
                reConnectToServer();
                deleteSuccess = client.deleteSlot(queueName, slotInfo, nodeId);
            } catch (TException e1) {
                handleCoordinatorChanges();
                throw new ConnectionException("Coordinator has changed", e);
            }
        }
        return deleteSuccess;
    }

    /**
     * Re-assign the slot when the last subscriber leaves the node
     *
     * @param nodeId    of this node
     * @param queueName name of the queue
     * @throws TException
     */
    public static synchronized void reAssignSlotWhenNoSubscribers(String nodeId,
                                                                  String queueName) throws ConnectionException {
        try {
            client = getServiceClient();
            client.reAssignSlotWhenNoSubscribers(nodeId, queueName);
        } catch (TException e) {
            try {
                //retry to do the operation once
                reConnectToServer();
                client.reAssignSlotWhenNoSubscribers(nodeId, queueName);
            } catch (TException e1) {
                handleCoordinatorChanges();
                throw new ConnectionException("Coordinator has changed", e);
            }
        }
    }

    /**
     * Delete all in-memory slot associations with a given queue. This is required to handle a queue purge event.
     *
     * @param queueName name of destination queue
     * @throws ConnectionException
     */
    public static synchronized void clearAllActiveSlotRelationsToQueue(String queueName) throws ConnectionException {

        try {
            client = getServiceClient();
            client.clearAllActiveSlotRelationsToQueue(queueName);
        } catch (TException e) {
            try {
                //retry to do the operation once
                reConnectToServer();
                client.clearAllActiveSlotRelationsToQueue(queueName);
            } catch (TException e1) {
                handleCoordinatorChanges();
                throw new ConnectionException("Coordinator has changed", e);
            }
        }
    }

    /**
     * Returns an instance of Slot Management service client which is used to communicate to the
     * thrift server. If it does not succeed in connecting to the server, it throws a  TTransportException
     *
     * @return a SlotManagementService client
     */
    private static SlotManagementService.Client getServiceClient() throws TTransportException {
        if (client == null) {
            HazelcastAgent hazelcastAgent = HazelcastAgent.getInstance();
            String thriftCoordinatorServerIP = hazelcastAgent.getThriftServerDetailsMap().get(
                    SlotCoordinationConstants.THRIFT_COORDINATOR_SERVER_IP);
            int thriftCoordinatorServerPort = Integer.parseInt(
                    hazelcastAgent.getThriftServerDetailsMap().
                            get(SlotCoordinationConstants.THRIFT_COORDINATOR_SERVER_PORT));
            transport = new TSocket(thriftCoordinatorServerIP,
                    thriftCoordinatorServerPort);
            try {
                transport.open();
                TProtocol protocol = new TBinaryProtocol(transport);
                return new SlotManagementService.Client(protocol);
            } catch (TTransportException e) {
                log.error("Could not initialize the Thrift client. " + e.getMessage(), e);
                throw new TTransportException(
                        "Could not initialize the Thrift client. " + e.getMessage(), e);
            }

        }
        return client;
    }

    /**
     * Start the thrift server reconnecting thread when the coordinator of the cluster is changed.
     */
    private static void handleCoordinatorChanges() {
        resetServiceClient();
        if (!isReconnectingStarted()) {
            setReconnectingFlag(true);
        }
        startServerReconnectingThread();
    }

    /**
     * Set mbThriftClient to null
     */
    private static void resetServiceClient() {
        client = null;
        transport.close();
    }

    /**
     * Try to reconnect to server by taking latest values in the hazelcalst thrift server details
     * map
     *
     * @throws TTransportException when connecting to thrift server is unsuccessful
     */
    private static void reConnectToServer() throws TTransportException {
        int thriftCoordinatorServerPort = 0;
        String thriftCoordinatorServerIP = null;
        Long reconnectTimeout = (Long) AndesConfigurationManager.readValue
                (AndesConfiguration.COORDINATOR_THRIFT_RECONNECT_TIMEOUT) * 1000;
        try {
            //Reconnect timeout set because Hazelcast coordinator may still not elected in failover scenario
            Thread.sleep(reconnectTimeout);
            HazelcastAgent hazelcastAgent = HazelcastAgent.getInstance();
            thriftCoordinatorServerIP = hazelcastAgent.getThriftServerDetailsMap().get(
                    SlotCoordinationConstants.THRIFT_COORDINATOR_SERVER_IP);
            thriftCoordinatorServerPort = Integer.parseInt(
                    hazelcastAgent.getThriftServerDetailsMap().
                            get(SlotCoordinationConstants.THRIFT_COORDINATOR_SERVER_PORT));
            transport = new TSocket(thriftCoordinatorServerIP, thriftCoordinatorServerPort);
            log.info("Reconnecting to Slot Coordinator " + thriftCoordinatorServerIP + ":"
                    + thriftCoordinatorServerPort);

            transport.open();
            TProtocol protocol = new TBinaryProtocol(transport);
            client = new SlotManagementService.Client(protocol);
        } catch (TTransportException e) {
            log.error("Could not connect to the Thrift Server " + thriftCoordinatorServerIP + ":" +
                    thriftCoordinatorServerPort + e.getMessage(), e);
            throw new TTransportException(
                    "Could not connect to the Thrift Server " + thriftCoordinatorServerIP + ":" +
                            thriftCoordinatorServerPort, e);
        } catch (InterruptedException ignore) {
        }
    }

    /**
     * This thread is responsible of reconnecting to the thrift server of the coordinator until it
     * gets succeeded
     */
    private static void startServerReconnectingThread() {
        new Thread() {
            public void run() {
                /**
                 * this thread will try to connect to thrift server while reconnectingStarted
                 * flag is true
                 * After successfully connecting to the server this flag will be set to true.
                 * While loop is therefore intentional.
                 */
                SlotDeliveryWorkerManager slotDeliveryWorkerManager = SlotDeliveryWorkerManager
                        .getInstance();
                while (reconnectingStarted) {

                    try {
                        reConnectToServer();
                        /**
                         * If re connect to server is successful, following code segment will be
                         * executed
                         */
                        reconnectingStarted = false;
                        slotDeliveryWorkerManager.startAllSlotDeliveryWorkers();
                    } catch (TTransportException e) {
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException ignored) {
                            //silently ignore
                        }
                    }

                }
            }
        }.start();
    }

    /**
     * A flag to specify whether the reconnecting to thrift server is happening or not
     *
     * @return whether the reconnecting to thrift server is happening or not
     */
    public static boolean isReconnectingStarted() {
        return reconnectingStarted;
    }

    /**
     * Set reconnecting flag
     *
     * @param reconnectingFlag  flag to see whether the reconnecting to the thrift server is
     *                          started
     */
    public static void setReconnectingFlag(boolean reconnectingFlag) {
        reconnectingStarted = reconnectingFlag;
    }

    /**
     * Update the safeZone message ID of this node
     * @param safeZoneMessageID safe zone message ID
     * @param nodeID node ID of this node
     * @return global safeZone
     * @throws ConnectionException when MB thrift server is down
     */
    public static synchronized long updateSlotDeletionSafeZone(long safeZoneMessageID, String nodeID) throws ConnectionException {
        long globalSafeZone = 0;
        try {
            client = getServiceClient();
            globalSafeZone = client.updateCurrentMessageIdForSafeZone(safeZoneMessageID, nodeID);
        } catch (TException e) {
            try {
                //retry once
                reConnectToServer();
                globalSafeZone = client.updateCurrentMessageIdForSafeZone(safeZoneMessageID, nodeID);
                return globalSafeZone;
            } catch (TException e1) {
                handleCoordinatorChanges();
                throw new ConnectionException("Coordinator has changed", e);
            }
        }
        return globalSafeZone;
    }
}


Over the last 40 years, Cyprus has firmly established itself as a reputable international financial centre. The low taxation, freedom of exchange controls, excellent telecommunication facilities, as well as numerous other advantages offered, have brought Cyprus to the forefront of international financial centres.
A large number of foreign owned Cyprus companies are currently active on the island either through their own fully-fledged offices on the island or by using local accountants and lawyers as their representatives.


Poor customer service and website and design issues. At Egg Design, we do our very best to avoid any problems related to either category. We wanted to explore these common web design project issues and look at what it takes to avoid them.
There are a couple of common complaints that fall into the "poor customer service" category. This means that if a company prioritises great customer service, then these issues shouldn't arise.
One of the most common web design project issues that people have about web designers is that after signing a contract and receiving payment, they become unresponsive. So whether you're looking for help with a typo you noticed, or you have a question about a particular functionality, this web design company is nowhere to be found.
We prefer to do most things by email so it's easy for clients to refer back to. We also use programs like Dropbox and Avada to manage projects. We've been told we're sometimes too fast when responding to client messages!
Another complaint that is often seen on the Internet is that the website takes too long to complete. At Egg Design, we strive to maintain consistent contact with our clients. This keeps projects on track.
What about being hoodwinked by hidden costs? You may get started on a web design project, and it seems like it will be affordable and within budget, even below budget. Then you discover certain vital features that should be standard on any website are not included in the price. So you end up spending even more than some of the higher quotes you received from other web designers. Unfortunately, among unethical web design companies, this isn't an uncommon occurrence.
In regards to this issue, we write our contracts as inclusive as possible, in addition to creating terms and conditions to avoid any confusion down the road. Providing a clear project scope to our clients is a top priority to avoid any issues later.
Website design is a whole other category of complaints. It's true that a finished website may not look exactly like the concept initially agreed upon. Communication throughout the project can go a long way though.
The top problem is that people and businesses can't make changes to their website on their own. So this means that they have to contact their web designer in order to make changes. Now if you are considering a major change or a new page appearance, then perhaps you should reach out to your web designer. However, we believe that all of our clients should have the opportunity to save money by being able to make edits to things like images and text. We set up most of our clients' websites on WordPress (WordPress powers about 30% of all websites!
There's nothing like paying thousands of euros and to end up with a product that doesn't look like how you imagined it would. We work with all of our clients to create a concept that embodies their brand and message. Also, these days the ability to create "development" websites means a client can see a design on an actual site mock-up.
Due to our high level of communication with every client, the finished site is exactly what they want. During the concept development phase, we send every client a thorough questionnaire about the project. Clients also receive sample websites to establish style likes and dislikes.
Taking the time to understand what each client wants and needs from their site is a critical step we never skip. Ultimately, you need great communication to ensure that a web design project moves from start to finish as efficiently as possible. We take great pride in delivering beautiful and functional websites. But our customer service is what creates a smooth experience from start to finish.
Interested in web design for your business? Contact us today to get your quote!
Ruthie is a content marketer and creator who specialises in helping B2B service companies generate leads through their online content. She enjoys the challenge of helping her clients go beyond their offerings' features to the true benefits for their customers.