Friday, August 24, 2018

Nesting Excel formulas to extract e-mail address top-level domain

I want to extract the top-level domain from e-mail addresses using Excel formulas.

I tried it first with concatenating RIGHT(..) Formulas and splitting for the dot. Sadly I do not know how to do this recursively with excel formulas, so I swapped to deleting all characters except the last 4. Now the problem is, when I split my formulas into single cells it works perfectly fine. If I try to use them together, I get only the output of the first inner Formula. How do I fix this?

=RIGHT(B8; LEN(B8)-(LEN(B8)-4))
=RIGHT(BF8;LEN(BF8)-FIND(".";BF8))

These are the formulas split into single cells. And here both together

=RIGHT(RIGHT(B8; LEN(B8)-(LEN(B8)-4));LEN(B8)-FIND(".";B8))

I get the same return value as in the first row from this formula

=RIGHT(B8; LEN(B8)-(LEN(B8)-4))

Solved

This =RIGHT(B8; LEN(B8)-(LEN(B8)-4)) is just a uselessly complicated version of =RIGHT(B8; 4).

Substituting this for BF8 in

=RIGHT(BF8;LEN(BF8)-FIND(".";BF8))

yields this

=RIGHT(RIGHT(B8; 4);LEN(RIGHT(B8; 4))-FIND(".";RIGHT(B8; 4)))

which can be simplified as

=RIGHT(RIGHT(B8; 4);4-FIND(".";RIGHT(B8; 4)))

So that's the answer to your question.

But note that this will fail when parsing e-mail addresses whose top-level domain name has more than 3 characters! So it won't work for e.g. test@test.info. Note that top-level domains can be up to 63 characters long!

In this earlier answer, I give a more general solution to this problem, not limited to searching a predetermined number of characters from the right.

=MID(B8;FIND(CHAR(1);SUBSTITUTE(B8;".";CHAR(1);LEN(B8)-LEN(SUBSTITUTE(B8;".";""))))+1;LEN(B8))

returns everything after the last . in the string.


Dot character may appear in left part if e-mail, like: john.johnson@email.com So, you can't just find "." you need firstly find @, then find dot in right substring. Tehese are your steps:

1. =FIND("@"; B8)
find @ character place

2. =RIGHT(B8;LEN(B8) - FIND("@"; B8))
get substring right from @

3. =FIND(".";RIGHT(B8;LEN(B8) - FIND("@"; B8)))
find "." in step 2 substring

4. =RIGHT(RIGHT(B8;LEN(B8) - FIND("@"; B8)); LEN(RIGHT(B8;LEN(B8) - FIND("@"; B8))) - FIND(".";RIGHT(B8;LEN(B8) - FIND("@"; B8))))
get right(step2; len(step2) - step3)

Monday, August 20, 2018

Flask routing, multiple route functions

So, to achieve a seemless web app, not having the page reload on every new view change is pretty essential. To do this, I'm using socketio, and converting to base64 on the backend so html isn't lost in transmission.

However, when the user goes directly to the url, I want them to be able to see the same page as if a user was shown the page if they clicked the link on the index page, then loading it via socketio. (index → page)

This is the socketio routing decorator class inspired by a blog post by Ainsley Jones

class socketio_route:
    def __init__(self):
        self.routes = {}

    def route(self, rule):
        if rule[0] == '/':
            rule = rule[1::]
        def decorator(f):
            self.routes[rule] = f
            return f
        return decorator

    def serve(self, path):
        view_func = self.routes.get(path)
        if view_func:
            return view_func(False)

which is then used in conjunction with the standard @app.route('/') flask decorator.

@app.route('/branches')
@skt.route('/branches')
def route_branches(fullpage=True):
    values = {"data": {'branch': 'master'}}
    page = render_template('default.html', **values)

    if fullpage == False:
        socketio.emit('page', base64.b64encode(page), namespace='/page')
    else:
        return render_template('index.html', socket_preload_content=page)

This returns the bare-bones page if it is accessed via socketio, and the full page (a render_template of the initial render_template) if it is accessed via the default method; directly.

I'm using flask_socketio to handle all things socketio.



Question

So, my question is, is it possible to integrate all of this into a single route decorator, or extend the existing flask @app.route() decorator?

Maybe something like this for the custom route?

@CUSTOM.route('/branches')
def branches():
    values = {"data": {'branch': 'master'}}
    return render_template('default.html', **values)

which would return either

socketio.emit('page', base64.b64encode(OUTPUT_FROM_ABOVE), namespace='/page')

or

render_template('index.html', socket_preload_content=OUTPUT_FROM_ABOVE)

depending on the way it was called.



I looked into flask's app.add_url_rule but was confused as to how I might integrate this into my existing socketio_route decorator class.

Can anyone suggest as to how I might go about this?

Solved

So to fix this, I did actually end up using flask's app.add_url_rule.

The socketio_route is a tad different, mainly in the fact that it directly emits a page.

class socketio_route:
    def __init__(self):
        self.routes = {}

    def route(self, rule, f):
        if rule[0] == '/':
            rule = rule[1::]
        self.routes[rule] = f

    def serve(self, path):
        view_func = self.routes.get(path)
        if view_func:
            socketio.emit('page', base64.b64encode(view_func(fullpage=False)), namespace='/page')

skt = socketio_route()

the custom decorator I wrote adds a route to both socketio_route and app.

def dual_route(rule):
    def decorator(f):
        @wraps(f)
        def decorated_function(fullpage=True, *args, **kwargs):
            if fullpage == False:
                return f(*args, **kwargs)
            else:
                return render_template('index.html', socket_preload_content=f(*args, **kwargs))
        app.add_url_rule(rule, decorated_function.__name__, decorated_function)
        skt.route(rule, decorated_function)
        return decorated_function
    return decorator

and then I can just call it by:

@dual_route('/branches')
def route_branches():
    values = {"data": {'branch': 'master'}}
    return render_template('default.html', **values)

Sunday, August 19, 2018

LockScreen Player is not appearing once the screen is locked in actual device.

I'm new to swift and I have a AVPlayer which is playing fine on a particular screen. My objective is to play the same audio on lock-screen mode. So far this is what I have done and the code as bellow. for some reason I don't see the player widget on lock-screen mood at all. What am I doing wrong here.

class MyAudiosViewController: UIViewController,UITableViewDelegate,UITableViewDataSource,AVAudioPlayerDelegate {


@IBAction func playButtonPressed(_ sender: Any) {
        if(currentRowSelected != nil ){
            if AudioPlayer.isPlaying() {
                AudioPlayer.pause()
                playButton.setImage(UIImage(named: "play_button"), for: UIControlState.normal)
            } else {
                AudioPlayer.play()
                playButton.setImage(UIImage(named: "pause_button"), for: UIControlState.normal)
            }

            setUpBackgroundMode()

        }else{
            "Track is not selected from list"
        }

    }

}


 extension MyAudiosViewController {

    override func remoteControlReceived(with event: UIEvent?) {
        if let receivedEvent = event {
            if (receivedEvent.type == .remoteControl) {
                switch receivedEvent.subtype {
                case .remoteControlTogglePlayPause:
                   playButtonPressed(AudioPlayer.isPlaying())
                case .remoteControlPlay:
                playButtonPressed(AudioPlayer.player?.play())
                case .remoteControlPause:
                   playButtonPressed(AudioPlayer.player?.pause())
                case .remoteControlNextTrack:
                     print("next pressed")
                case .remoteControlPreviousTrack:
                     print("previous pressed")
                default:
                    print("received sub type \(receivedEvent.subtype) Ignoring")
                }
            }
        }
    }

    func setUpBackgroundMode() {
        if  let positionSong = AudioPlayer.getPlayingIndex() {
            let song = songDetailsArray[positionSong]
            let songData = song.audioDetails

        MPNowPlayingInfoCenter.default().nowPlayingInfo = [
            MPMediaItemPropertyTitle: songData?.title ?? "",
            MPMediaItemPropertyArtist: songData?.healerName ?? "",
            MPMediaItemPropertyPlaybackDuration: 
            self.player?.currentItem?.asset.duration
        ]
            UIApplication.shared.beginReceivingRemoteControlEvents()

        becomeFirstResponder()
       }
      }
  }

Solved

Try this and check this demo

declare this variable in your playerviewcontroller

var audioSession = AVAudioSession.sharedInstance()

in viewDidiLoad add this code

    try! self.audioSession.setCategory(AVAudioSessionCategoryPlayback)
    try! self.audioSession.setActive(true)

    UIApplication.shared.beginReceivingRemoteControlEvents()
    self.becomeFirstResponder()

pass data to this func or yours

var nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
var remoCommandCenter = MPRemoteCommandCenter.shared()
func updateNowPlayingInfo(trackName:String,artistName:String,img:UIImage) {

    var art = MPMediaItemArtwork(image: img)
    if #available(iOS 10.0, *) {
        art = MPMediaItemArtwork(boundsSize: CGSize(width: 200, height: 200)) { (size) -> UIImage in
            return img
        }
    }

    nowPlayingInfoCenter.nowPlayingInfo = [MPMediaItemPropertyTitle: trackName,
                                           MPMediaItemPropertyArtist: artistName,
                                           MPMediaItemPropertyArtwork : art]

    remoCommandCenter.seekForwardCommand.isEnabled = false
    remoCommandCenter.seekBackwardCommand.isEnabled = false
    remoCommandCenter.previousTrackCommand.isEnabled = false
    remoCommandCenter.nextTrackCommand.isEnabled = false
    remoCommandCenter.togglePlayPauseCommand.isEnabled = false
}

call above function when your load new song.

  func loadNewSong() {
      //your audio player code.
      updateNowPlayingInfo(trackName:"just Like that", artistName:"LeoJam",img:UIImage(string:"img")!)
  }

Saturday, August 18, 2018

Building an indeterminate array of functions to pass to $q.all

I'm building an array of functions to pass to $q.all, and I'm wondering if I'm doing it correctly, or if each function will execute separately as I push it into the array.

My code looks like this:

function setParallelRequests() {
    var promiseArray = [];
    var counter;

    for (counter; counter < factory.cards.length; counter++) {

        var data = {
            reference: factory.cards[counter].reference
        };

        promiseArray.push(fetchState(data));
    }

    return $q.all(promiseArray)
        .then(function(response){

            return factory.cards;

        }).catch(function(error){
            return $q.reject(error);
        });
}

function fetchState(data) {

    return $http.post('/returnState', data)
       .then(function(response) {

            alert("got the state!");

        })
        .catch(function(error){

            return $q.reject(error);
         });

}

Will the code execute as I'm pushing it in the array or will it only execute when $q.all runs?

If it isn't done correctly, what would be the best way to do it?