| author: | Ian Bicking<EMAIL_ADDRESS>|
|---|---|
| revision: | $Rev$ |
| date: | $LastChangedDate$ |
Contents
This document is an introduction to how you can extend paster and Paste Script for your system – be it a framework, server setup, or whatever else you want to do.
paster is a two-level command, where the second level (e.g., paster help, paster create, etc) is pluggable.
Commands are attached to Python Eggs, i.e., to the package you distribute and someone installs. The commands are identified using entry points.
To make your command available do something like this in your setup.py file:
from setuptools import setup
setup(...
entry_points="""
[paste.paster_command]
mycommand = mypackage.mycommand:MyCommand
[paste.global_paster_command]
myglobal = mypackage.myglobal:MyGlobalCommand
""")
This means that paster mycommand will run the MyCommand command located in the mypackage.mycommand module. Similarly with paster myglobal. The distinction between these two entry points is that the first will only be usable when paster is run inside a project that is identified as using your project, while the second will be globally available as a command as soon as your package is installed.
So if you have a local command, how does it get enabled? If the person is running paster inside their project directory, paster will look in Project_Name.egg-info/paster_plugins.txt which is a list of project names (the name of your package) whose commands should be made available.
This is for frameworks, so frameworks can add commands to paster that only apply to projects that use that framework.
The command objects (like MyCommand) are subclasses of paste.script.command.Command. You can look at that class to get an idea, but a basic outline looks like this:
from paste.script import command
class MyCommand(command.Command):
max_args = 1
min_args = 1
usage = "NAME"
summary = "Say hello!"
group_name = "My Package Name"
parser = command.Command.standard_parser(verbose=True)
parser.add_option('--goodbye',
action='store_true',
dest='goodbye',
help="Say 'Goodbye' instead")
def command(self):
name = self.args[0]
if self.verbose:
print "Got name: %r" % name
if self.options.goodbye:
print "Goodbye", name
else:
print "Hello", name
max_args and min_args are used to give error messages. You can also raise command.BadCommand(msg) if the arguments are incorrect in some way. (Use None here to give no restriction)
The usage variable means paster mycommand -h will give a usage of paster mycommand [options] NAME. summary is used with paster help (describing your command in a short form). group_name is used to group commands together for paste help under that title.
The parser object is an optparse <http://python.org/doc/current/lib/module-optparse.html> OptionParser object. Command.standard_parser is a class method that creates normal options, and enables options based on these keyword (boolean) arguments: verbose, interactive, no_interactive (if interactive is the default), simulate, quiet (undoes verbose), and overwrite. You can create the parser however you want, but using standard_parser() encourages a consistent set of shared options across commands.
When your command is run, .command() is called. As you can see, the options are in self.options and the positional arguments are in self.args. Some options are turned into instance variables – especially self.verbose and self.simulate (even if you haven’t chosen to use those options, many methods expect to find some value there, which is why they are turned into instance variables).
There are quite a few useful methods you can use in your command. See the Command class for a complete list. Some particulars:
run_command(cmd, arg1, arg2, ..., cwd=os.getcwd(), capture_stderr=False):
Runs the command, respecting verbosity and simulation. Will raise an error if the command doesn’t exit with a 0 code.
insert_into_file(filename, marker_name, text, indent=False):
Inserts a line of text into the file, looking for a marker like -*- marker_name -*- (and inserting just after it). If indent=True, then the line will be indented at the same level as the marker line.
ensure_dir(dir, svn_add=True):
Ensures that the directory exists. If svn_add is true and the parent directory has an .svn directory, add the new directory to Subversion.
ensure_file(filename, content, svn_add=True):
Ensure the file exists with the given content. Will ask the user before overwriting a file if --interactive has been given.
The other pluggable part is “templates”. These are used to create new projects. Paste Script includes one template itself: basic_package which creates a new setuptools package.
To enable, add to setup.py:
setup(...
entry_points="""
[paste.paster_create_template]
framework = framework.templates:FrameworkTemplate
""")
FrameworkTemplate should be a subclass of paste.script.templates.Template. An easy way to do this is simply with:
from paste.script import templates
class FrameworkTemplate(templates.Template):
egg_plugins = ['Framework']
summary = 'Template for creating a basic Framework package'
required_templates = ['basic_package']
_template_dir = 'template'
use_cheetah = True
egg_plugins will add Framework to paste_plugins.txt in the package. required_template means those template will be run before this one (so in this case you’ll have a complete package ready, and you can just write your framework files to it). _template_dir is a module-relative directory to find your source files.
The source files are just a directory of files that will be copied into place, potentially with variable substitutions. Three variables are expected: project is the project name (e.g., Project-Name), package is the Python package in that project (e.g., projectname) and egg is the project’s egg name as generated by setuptools (e.g., Project_Name). Users can add other variables by adding foo=bar arguments to paster create.
Filenames are substituted with +var_name+, e.g., +package+ is the package directory.
If a file in the template directory ends in _tmpl then it will be substituted. If use_cheetah is true, then it’s treated as a Cheetah template. Otherwise string.Template is used, though full expressions are allowed in ${expr} instead of just variables.
See the templates module for more.


EXTENSION_ID = i18n.get '@@extension_id'
iOrder
(c) 2013 Alasdair Mercer
Freely distributable under the MIT license.
For all details and documentation:
http://neocotic.com/iOrder
Extension ID being used by iOrder.
EXTENSION_ID = i18n.get '@@extension_id'
Domain of this extension's homepage.
HOMEPAGE_DOMAIN = 'neocotic.com'
Extension ID of the production version of iOrder.
REAL_EXTENSION_ID = 'kflemogpkbophbipihnbcmlplbihbdhb'
Indicate whether or not iOrder has just been installed.
isNewInstall = no
Indicate whether or not iOrder is currently running the production build.
isProductionBuild = EXTENSION_ID is REAL_EXTENSION_ID
Number of status updates since the user last cleared it.
updates = 0
Inject and execute install.coffee
within each of the tabs provided (where valid).
executeScriptsInExistingTabs = (tabs) ->
log.trace()
log.info 'Retrieved the following tabs...', tabs
for tab in tabs when tab.url.indexOf(HOMEPAGE_DOMAIN) isnt -1
chrome.tabs.executeScript tab.id, file: 'lib/install.js'
Inject and execute install.coffee
within all the tabs (where valid) of each Chrome window.
executeScriptsInExistingWindows = ->
log.trace()
chrome.windows.getAll null, (windows) ->
log.info 'Retrieved the following windows...', windows
for win in windows
chrome.tabs.query windowId: win.id, executeScriptsInExistingTabs
Return the number of status updates detected by this extension for an order since the specified time.
getOrderStatusUpdates = (order, lastRead) ->
log.trace()
count = 0
count++ for update in order.updates when update.timeStamp > lastRead
count
Return the recognized status that matches the specified text
.
getStatus = (text) ->
log.trace()
ext.config.apple.status[getStatusIndex text]
Return the index of the recognized status that matches the specified text
.
getStatusIndex = (text) ->
log.trace()
text = text?.trim()
return i for status, i in ext.config.apple.status when status.value.test text
-1
Return the total number of detected status updates for all existing orders since the last time badges were cleared.
getStatusUpdates = ->
log.trace()
count = 0
lastRead = store.get 'lastRead'
count += getOrderStatusUpdates order, lastRead for order in ext.orders
count
Return all windows managed by this extension that are displaying a page that begins with the specified URL.
getWindows = (url) ->
log.trace()
chrome.extension.getViews(type: 'tab').filter (element) ->
element.location.href.indexOf(url) is 0
Determine whether or not an order already has the specified status.
isOrderStatusNew = (order, status) ->
log.trace()
return no for update in order.updates when update.status is status
yes
Ensure any badge notification is cleared.
markRead = (retainTimeStamp) ->
log.trace()
updates = 0
store.set 'lastRead', $.now() unless retainTimeStamp
do setBadge
Update the UI so the clear button vanishes.
do updatePopup
Attempt to notify the user of any unread status updates.
If there are no status updates, remove any visible badge.
notify = ->
log.trace()
notifications = store.get 'notifications'
oldUpdates = updates
updates = getStatusUpdates()
Update/clear badge depending on setting and updates available.
setBadge if notifications.badges then updates or ''
Show the notification when new updates are found.
if updates > oldUpdates
ext.notification.description = i18n.get 'notification'
ext.notification.title = i18n.get 'name'
do showNotification
else
ext.reset()
Listener for internal messages.
This function will handle the message based on its type and the data provided.
onMessage = (message, sender, sendResponse) ->
log.trace()
order = {}
url = ''
Attempt to return the order whose details match the specified criteria.
getOrder = (data) ->
ext.queryOrder (order) -> order.key is data.key
Check what needs to be done... and then do it.
switch message.type
when 'clear' then do markRead
when 'options'
Try using existing tabs for the options page before creating one.
url = utils.url 'pages/options.html'
selectOrCreateTab url, (isNew) ->
return if isNew
win.options.refresh() for win in getWindows url
when 'info', 'version' then sendResponse? id: EXTENSION_ID, version: ext.version
when 'refresh' then ext.updateOrders()
when 'track'
order = getOrder message.data
chrome.tabs.create url: order.trackingUrl if order and order.trackingUrl
when 'viewAll' then chrome.tabs.create url: ext.config.apple.url.list
when 'view'
order = getOrder message.data
chrome.tabs.create url: ext.getOrderUrl order if order
log.debug "Finished handling #{message.type} message"
Attempt to select a tab in the current window displaying a page whose location begins with the
specified URL.
If no existing tab exists a new one is simply created.
selectOrCreateTab = (url, callback) ->
log.trace()
chrome.windows.getCurrent (win) ->
log.debug 'Retrieved the following window...', win
chrome.tabs.query windowId: win.id, (tabs) ->
log.debug 'Retrieved the following tabs...', tabs
Try to find an existing tab.
for tab in tabs
if tab.url.indexOf(url) is 0
existingTab = tab
break
if existingTab
Found one! Now to select it.
chrome.tabs.update existingTab.id, selected: yes
callback? no
else
Ach well, let's just create a new one.
chrome.tabs.create url: url
callback? yes
Set the badge text to the specified string.
If no string is specified the badge is cleared.
setBadge = (str = '') ->
log.trace()
chrome.browserAction.setBadgeText text: String str
Display a desktop notification informing the user on new order updates.
Also, ensure that ext
is reset and that notifications are only displayed if the user has
enabled the corresponding option (which is enabled by default).
showNotification = ->
log.trace()
if store.get 'notifications.enabled'
webkitNotifications.createHTMLNotification(utils.url 'pages/notification.html').show()
else
ext.reset()
Send an AJAX request to the specified order's page on the Apple US store and parses the response
to update the order's properties.
If an error occurs during the update process assign a short description to order.error
.
updateOrder = (order, callback) ->
log.trace()
$.get(ext.getOrderUrl order)
.done (data) ->
Probably won't happen; more of a sanity check.
return order.error = 'update_invalid_page_error' unless data
Extract the relevant elements wrapped in jQuery goodness.
heading = $(data).find '.order .ship-group .sb-heading'
status = heading.find 'h4 span:first-child'
trackingUrl = heading.find """
.group-actions tr:first-child td a[href^='#{ext.config.apple.url.track}']
"""
Dig deeper and try and get the actual values.
status = getStatusIndex if status.length then status.text() else ''
trackingUrl = if trackingUrl.length then trackingUrl.attr 'href' else ''
if status >= 0
OK, it was valid; but is it new???
if isOrderStatusNew order, status
Right! It was valid and new! Just add it already.
order.updates.push
status: status
timeStamp: $.now()
else
Bad user data or extension could need updated.
return order.error = 'update_invalid_status_error'
Only update the Track link if it was found.
order.trackingUrl = trackingUrl if trackingUrl
Clear any pre-existing errors.
order.error = ''
.fail ->
Something went wrong.
order.error = 'update_page_not_found_error'
.always ->
Done! Now let's tell the boss.
callback?.apply updateManager, [order]
Build the HTML to populate the popup with to optimize popup loading times and updates any popup currently being displayed.
updatePopup = ->
log.trace()
do buildPopup
chrome.extension.getViews(type: 'popup')[0]?.popup.init()
Transform specific sections of the data loaded from configuration.json
so that they're more
useable and localized.
buildConfig = ->
log.trace()
do buildFrequencies
do buildStatus
Transform the configuration frequencies into useable localized options.
buildFrequencies = ->
log.trace()
for mins, i in ext.config.frequencies
hours = mins / 60
ext.config.frequencies[i] = if mins is -1
text: i18n.get 'freq_disabled'
value: mins
else
text: (
if hours < 1
i18n.get 'freq_minutes', [mins]
else if hours is 1
i18n.get 'freq_hour'
else
i18n.get 'freq_hours', [hours]
)
value: mins * 60 * 1000
Transform the configuration status into useable localized options.
buildStatus = ->
log.trace()
for status, i in ext.config.apple.status
ext.config.apple.status[i] =
text: i18n.get "status_#{i}_text"
value: /// ^ #{status} $ ///i
Create a tr
element to represent order
.
The element should then be inserted in to the tbody
element in the popup page but is created
here to optimize display times of the popup window.
buildOrder = (order) ->
log.trace()
log.debug "Creating popup table for #{order.label} (#{order.number})"
row = $ '<tr/>'
row.addClass 'error' if order.error
column = $ '<td/>'
if order.error
column.append $ '<i/>',
class: 'icon-exclamation-sign'
title: i18n.get order.error
column.append $ '<strong/>', text: order.label
column.append '<br/>'
column.append $ '<a/>',
'data-order-action': 'view'
'data-order-key': order.key
text: order.number
title: i18n.get 'pop_order_title'
row.append column
column = $ '<td/>'
column.append $ '<span/>', text: ext.getStatusText order
row.append column
column = $ '<td/>'
Found the track link so I'll share it with the user. I'm good like that.
if order.trackingUrl
column.append $ '<a/>',
'data-order-action': 'track'
'data-order-key': order.key
text: i18n.get 'pop_track_text'
title: i18n.get 'pop_track_title'
else
column.append ' '
row.append column
Build the HTML to populate the popup with to optimize popup loading times.
buildPopup = ->
log.trace()
rows = $()
Generate the HTML for each order.
rows = rows.add buildOrder order for order in ext.orders
Add a generic message to state the obvious... that the list is empty.
if rows.length is 0
rows = rows.add $('<tr/>').append $ '<td/>',
class: 'empty'
colspan: 3
html: i18n.get 'empty'
ext.ordersHtml = $('<div/>').append(rows).html()
Build the HTML to indicate in a user-friendly manner the time since/until that specified.
buildTimeAgo = (time) ->
log.trace()
time ?= $.now()
time = new Date time if 'date' isnt $.type time
timeAgo = $('<abbr/>', title: time.toISOString()).timeago()
$('<div/>').append(timeAgo).html()
Handle the conversion/removal of older version of settings that may have been stored previously
by ext.init
.
init_update = ->
log.trace()
Update the update progress indicator itself.
if store.exists 'update_progress'
store.modify 'updates', (updates) ->
progress = store.remove 'update_progress'
for own namespace, versions of progress
updates[namespace] = if versions?.length then versions.pop() else ''
Create updater for the settings
namespace.
updater = new store.Updater 'settings'
isNewInstall = updater.isNew
Define the processes for all required updates to the settings
namespace.
updater.update '1.1.0', ->
log.info 'Updating general settings for 1.1.0'
freq = ext.config.frequencies[1].value
frequency = store.get 'frequency'
store.set 'frequency', freq if frequency > -1 and frequency < freq
updater.update '1.2.0', ->
log.info 'Updating general settings for 1.2.0'
notifications = store.get 'notifications'
store.set 'notifications',
badges: store.get('badges') ? on
duration: store.get('notificationDuration') ? 3000
enabled: if $.type(notifications) is 'boolean' then notifications else yes
store.remove 'badges', 'notificationDuration'
Initialize order
and its properties.
initOrder = (order) ->
log.trace()
order.error ?= ''
order.code ?= ''
order.email ?= ''
order.label ?= ''
order.number ?= ''
order.trackingUrl ?= ''
order.updates ?= []
for update in order.updates
update.status ?= -1
update.timeStamp ?= $.now()
order
Initialize the persisted managed orders.
initOrders = ->
log.trace()
do initOrders_update
Initialize all orders to ensure their properties are valid.
store.modify 'orders', (orders) ->
initOrder order for order in orders
ext.updateOrders()
Handle the conversion/removal of older version of settings that may have been stored previously
by initOrders
.
initOrders_update = ->
log.trace()
Create updater for the orders
namespace.
updater = new store.Updater 'orders'
Define the processes for all required updates to the orders
namespace.
updater.update '1.2.0', ->
log.info 'Updating order settings for 1.2.0'
store.modify 'orders', (orders) ->
for order in orders
if order.error is 'update_status_not_found_error'
order.error = 'update_invalid_status_error'
order.key ?= utils.keyGen()
update.status = getStatusIndex update.status for update in order.updates
Initialize the timeago jQuery plugin.
initTimeAgo = ->
log.trace()
messageOrNull = (messageKey) -> i18n.get(messageKey) or null
numbers = messageOrNull 'ta_numbers'
numbers = if numbers? then numbers.trim().split /\s+/ else []
Apply localized strings to timeago.
$.timeago.settings.strings =
day: messageOrNull 'ta_day'
days: messageOrNull 'ta_days'
hour: messageOrNull 'ta_hour'
hours: messageOrNull 'ta_hours'
minute: messageOrNull 'ta_minute'
minutes: messageOrNull 'ta_minutes'
month: messageOrNull 'ta_month'
months: messageOrNull 'ta_months'
numbers: numbers
prefixAgo: messageOrNull 'ta_prefix_ago'
prefixFromNow: messageOrNull 'ta_prefix_from_now'
seconds: messageOrNull 'ta_seconds'
suffixAgo: messageOrNull 'ta_suffix_ago'
suffixFromNow: messageOrNull 'ta_suffix_from_now'
wordSeparator: i18n.get 'ta_word_separator'
year: messageOrNull 'ta_year'
years: messageOrNull 'ta_years'
Central manager for updating the orders.
This manager can handle concurrent start, stop and restart requests while also supporting repeat
(looping) functionality.
updateManager =
Unique interval identifier used to managed repeating updates.
id: undefined
Message stack used by the current update process.
Any start/stop/restart requests made while the manager is updating is added to this stack and
actioned upon completion of the process. Afterwards, the stack is cleared for the next process.
messages: []
Indicate whether or not the update manager is currently running through an update process.
updating: no
Restart the update manager, which may run once or start a repeating cycle based on the current
update frequency.
If this is called during an active update process the manager will restart upon completion.
restart: ->
log.trace()
log.info 'Restarting update manager'
frequency = store.get 'frequency'
I'm busy; I'll do it later.
return @messages.push 'restart' if @updating
Clear the current cycle, where applicable.
if @id
clearInterval @id
Ensure that it is disabled, where applicable.
@id = undefined if frequency is -1
Start a new cycle if required.
@id = setInterval @run, frequency if frequency isnt -1
Run the initial process.
do @run
Core of the update manager which actually performs the update process.
This process updates all orders and ensures the results are reflected in the popup.
run: ->
log.trace()
log.info 'Running update manager'
@progress = 0
@updating = yes
Update the UI to show that I'm busy.
do notify
do updatePopup
Called when the AJAX request has been parsed and read for each order.
This should be called regardless of errors being encountered.
updated = (order) ->
log.trace()
log.debug 'Updating order...', order
@progress++
Check if all orders have been updated; supports no orders.
if @progress >= ext.orders.length
@updating = no
Persist orders and update time stamp.
store.set 'orders', ext.orders
store.set 'lastUpdated', $.now()
Update the UI again to reflect the changes.
do notify
do updatePopup
Now read the message stack.
this[message]?() for message in @messages
@messages = []
Finish this now since no orders exist.
updated.apply this unless ext.orders.length
Update each order by parsing its page on the Apple US store.
updateOrder order, updated for order in ext.orders
Start the update manager, which may run once or start a repeating cycle based on the current update frequency.
start: ->
log.trace()
log.info 'Starting update manager'
frequency = store.get 'frequency'
Clear the current cycle, where applicable.
if frequency is -1
if @id
clearInterval @id
@id = undefined
else
I start twice for no one... see RESTART for that.
return if @id
Start a new cycle.
@id = setInterval @run, frequency
Run the initial process.
do @run
Stop the update manager.
If this is called during an active update process the manager will stop upon completion.
stop: ->
log.trace()
log.info 'Stopping update manager'
I'm busy; I'll do it later.
return @messages.push 'stop' if @updating
Clear the current cycle, where possible.
if @id
clearInterval @id
@id = undefined
ext = window.ext = new class Extension extends utils.Class
Configuration data loaded at runtime.
config: {}
Information specifying what should be displaying in the notification.
This should be reset after every update.
notification:
description: ''
descriptionStyle: ''
html: ''
icon: utils.url '../images/icon_48.png'
iconStyle: ''
title: ''
titleStyle: ''
List of orders currently being maintained.
This should always be an exact reflection of the orders persisted in localStorage
.
orders: []
Pre-prepared HTML for the popup to be populated using.
This should be updated whenever orders are changed/updated in any way as this is generated to
improve performance and load times of the popup frame.
ordersHtml: ''
Current version of iOrder.
version: ''
Initialize the background page.
This will involve initializing the settings, adding the message listeners and starting the
update manager.
init: ->
log.trace()
log.info 'Initializing extension controller'
Add support for analytics if the user hasn't opted out.
analytics.add() if store.get 'analytics'
$.getJSON(utils.url 'manifest.json')
.then (data) =>
It's nice knowing what version is running.
@version = data.version
.then $.getJSON(utils.url 'configuration.json')
.done (data) =>
Load and store the configuration data.
@config = data
do buildConfig
Begin initialization.
store.init
frequency: @config.frequencies[1].value
lastRead: $.now()
lastUpdated: $.now()
notifications: {}
orders: []
do init_update
store.modify 'notifications', (notifications) ->
notifications.badges ?= on
notifications.duration ?= 3000
notifications.enabled ?= yes
utils.onMessage 'extension', no, onMessage
do initTimeAgo
do initOrders
analytics.track 'Installs', 'New', @version, Number isProductionBuild if isNewInstall
Execute content scripts now that we know the version.
do executeScriptsInExistingWindows
Attempt to retrieve the details for the persisted update frequency.
getFrequency: ->
log.trace()
frequency = store.get 'frequency'
return freq for freq in @config.frequencies when freq.value is frequency
Return the URL of the page on the Apple store for the specified order
.
getOrderUrl: (order) ->
log.trace()
encode = encodeURIComponent
<EMAIL_ADDRESS>order.number}/#{encode order.email or order.code}"
Attempt to derive the status text to be displayed for the order.
The status text will either be that of the latest update or a single whitespace character if no
status updates have been detected yet for that order.
getStatusText: (order) ->
log.trace()
index = if order.updates?.length then order.updates[-1..][0].status else -1
@config.apple.status[index]?.text
Retrieve the HTML for a user-friendly timestamp representing the time since/until that specified.
getTimeAgoHtml: (time) -> buildTimeAgo time
Indicate whether any errors were encountered when orders were last updated.
hasErrors: ->
log.trace()
return yes for order in @orders when order.error
no
Indicate whether any order updates were detected.
hasUpdates: ->
log.trace()
updates > 0
Indicate whether the update manager is currently processing order updates.
isUpdating: ->
log.trace()
updateManager.updating
Retrieve the first order that passes the specified filter
.
queryOrder: (filter, singular = yes) ->
log.trace()
utils.query @orders, singular, filter
Retrieve all orders that pass the specified filter
.
queryOrders: (filter) -> @queryOrder filter, no
Reset the notification information associated with the current update process.
This should be called once updating has completed, regardless of it's outcome.
reset: ->
log.trace()
@notification =
description: ''
descriptionStyle: ''
html: ''
icon: utils.url '../images/icon_48.png'
iconStyle: ''
title: ''
titleStyle: ''
Update the local list of orders to reflect those persisted.
It is very important that this is called whenever orders may have been changed in order to
prepare the popup HTML and optimize performance, while also ensuring orders are correctly
managed during by the next update.
updateOrders: ->
log.trace()
@orders = store.get 'orders'
@orders.sort (a, b) -> a.index - b.index
do updatePopup
updateManager.restart()
Initialize ext
when the DOM is ready.
utils.ready -> ext.init()


HRMS MANAGEMENT SYSTEM
Forget Password
New password
Password is Required!
Confirm Password
New Password is Required!
I accept the Term And Condiition
Forget Password


The history API is no longer experimental; it's supported! You can read all about it at its new home:
history
chrome.history


--- layout: archive title: Zulip Chat Archive permalink: /stream/179818-Lean-Together-2019/topic/Documentation.20session.html ---
Could someone please post a short summary of the topic session on documentation?
I missed it so would also welcome any notes.
Also, it would be great to have something like "clojuredocs" for lean:
e.g. https://clojuredocs.org/clojure.data/diff
Last updated: Apr 24 2020 at 19:02 UTC


MR. PEABODY AND THE MERMAID and MIRANDA A film review by Matthew Ignoffo Copyright 1997 Matthew Ignoffo
These are the two classic mermaid movies. The British film MIRANDA made Glynis Johns a star and was so successful that it caused the American film studio Universal-International to create its own mermaid in the form of 20 year old Ann Blyth who had gained recognition as Joan Crawford's daughter in MILDRED PIERCE.
At the time neither film was considered a great work of cinema. But over the years, the two have gained in stature. MIRANDA can now be looked at as an allegory of man seeking to escape from the Victorian rigors of proper London society -- and society in general. The Doctor in the film has a chance to live with an aluring, naked mermaid in her sea-cave. His only chance of returning to formal society is if he will bring Miranda back with him. She is depicted as a worldly-wise, seductive fish-woman who bats her almond-shaped eyes at men and knows exactly what effect she is having on them. As a result, she becomes the embodiment of everything sensual and seductive -- she is the enchantment of the feminine sea itself calling man back to his more primitive instincts.
Lenore, the young mermaid in MR. PEABODY AND THE MERMAID, is naked too when Mr. Peabody catches her. Yet she is much more innocent than Miranda. Lenore is falling in love for the first time, whereas Miranda, even though she tells the Doctor he is her first man, may be carving notches in a seashell someplace. Lenore, thus, represents a completely different quality of the sea and of woman -- the innocence and the pure beauty that draw us to the water. Though the film was viewed as a vapid farce when it first came out, it now can be viewed as a story about man dealing with age and loss of youthful vigor. Mr. Peabody has just turned 50 which he describes as the youth of age and the age of youth. Catching Lenore may be seen as an allegory of his attempt to reassert his manhood in the face of oncoming age.
In both films, the men must give up their lovely mermaid lovers, but each man learns something about himself and life from the encounter with these mysterious creatures of the sea. The Doctor learns that he is not quite as adventurous as he thought he wanted to be, and Mr. Peabody learns that he can grow old gracefully and still keep his manly charm.
Though MR. PEABODY AND THE MERMAID is readily available on tape, MIRANDA and its 1954 sequel MAD ABOUT MEN are hardly to be found anywhere. They are not on tape and are seen only rarely on television. This is indeed a pity because the two "mermaid movies" as Ms Johns refers to her two mermaid films are charming and really did establish her as a star.
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


Cat food recalled over salmonella risk
by KNOE(CNN) - A cat food company is issuing a nationwide recall over possible salmonella contamination.
The Utah-based company Go Raw is recalling its Quest brand 2-pound frozen bags of beef cat food.
The recall was put into place after the Minnesota Department of Agriculture found a sample tested positive for salmonella.
Federal health officials say salmonella can not only affect animals that eat the products but can be a risk to humans who handle it.
For more information, including specific UPC codes, go to FDA.gov.
Copyright 2019 CNN. All rights reserved.


Tea of the Month
What's Steeping at The Tea Cozy?
Locations
Downtown
384 West 4th St
Suite 108
Portland, Maine
East Bayside
3433 Phisherman's Avenue
(Northwest Corner)
Portland, Maine
Oakdale
515 Crescent Avenue
Second Floor
Portland, Maine
What's Steeping at The Tea Cozy?
384 West 4th St
Suite 108
Portland, Maine
3433 Phisherman's Avenue
(Northwest Corner)
Portland, Maine
515 Crescent Avenue
Second Floor
Portland, Maine


--- layout: page title: "About" description: "This is what I do." header-img: "img/about-bg.jpg" group: navigation index: 0 ---
Hi, my name is Sven. I'm developing mobile Apps with Xamarin and MvvMCross since 2013 and the organizer of the Munich Mobile Xamarin & .NET Developers meetup group. So if you plan to come to Munich, feel free to let us know and we can probably plan a "Stammtisch" or "Xamarin Pizza and Beer".
On this blog I want to share some stuff about Xamarin and C# that came across in my projects.


Hello there, awesome person!
The-Nomadic
E-BOOKS
This is a link to e-book Solo Leveling!
This is a link to e-book The Boxer!
GitHub
This is a link to GitHub!


Docker Intermediate Commands¶
The following are the intermediate level commands that are needed to work with Docker. Open the terminal and run the commands.
Port Mapping¶
To open port on the container and map it to the port on dockerhost. Run the command
docker run -p 5000:80 nginx
where
-p
is used for port mapping.5000:80
means map port 80 of nginx container to port 5000 on dockerhost.
Volume Mapping¶
To keep the data of container persistant (keeping the data even when the container is deleted), Run the command
docker run -v /opt/data:/var/lib/mysql mysql
-v
is used for volumen mapping./opt/data:/var/lib/mysql
means map /var/lib/mysql directory in the container to /opt/data directory in dockerhost. Since MySQL server writes all data to /var/lib/mysql therefore the benefit of mounting the volume is that all data will be persistant even if the container is deleted.
Inspect command¶
To find the details of a container like port, mount volume etc. You can run the command
docker inspect <container_ID/Container_name>


Sai's Magical Guessing Machine
Guess the number the Sai is thinking of from 1 to 50 inclusive in 5 or less tries and you will get the password.
5
tries left
Guess


As you can see Containerization is better than Virtualization for most circumstances. While virtualization provides a better security bounding between the application and the hosts operating system, it uses more memory, it’s harder to scale, and it is less efficient over all compared to containerization. On the other hand, containerization is highly scalable, uses less memory space since it is running the host OS and it is very efficient when trying to work on big multiple part projects.
Virtualization vs Containerization
| Area | Virtualization | Containerization |
|---|---|---|
| Isolation | Provides complete isolation from the host operating system and the other VMs | Provides lightweight isolation from the host and other containers, but doesn’t provide as strong a security boundary as a VM |
| Operating System | Runs a complete operating system including the kernel, thus requiring more system resources such as CPU, memory, and storage | Runs the user-mode portion of an operating system, and can be tailored to contain just the needed services for your app using fewer system resources |
| Guest compatibility | Runs just about any operating system inside the virtual machine | Runs on the same operating system version as the host |
| Deployment | Deploy individual VMs by using Hypervisor software | Deploy individual containers by using Docker or deploy multiple containers by using an orchestrator such as Kubernetes |
| Persistent storage | Use a Virtual Hard Disk (VHD) for local storage for a single VM or a Server Message Block (SMB) file share for storage shared by multiple servers | Use local disks for local storage for a single node or SMB for storage shared by multiple nodes or servers |
| Load balancing | Virtual machine load balancing is done by running VMs in other servers in a failover cluster | An orchestrator can automatically start or stop containers on cluster nodes to manage changes in load and availability. |
| Networking | Uses virtual network adapters | Uses an isolated view of a virtual network adapter. Thus, provides a little less virtualization |


Sign in
Sign up
Male
Female
Rather not say
New here ?
Click the button below to sign up and be one of us !
Sign up
Already Registered ?
Click the button below to sign in .
Sign in


When you see
The love that lived in my heart
For how far it went for you
How against its own nature it had to
For so many blood it dripped from the stabs
Reality will awake you
Time will show you the enemies
And thus the light hidden within my heart


| SSW Update - 2012 Retrospective of SSW |
|
|
[the cutting edge ]
G'day Developers!
I thought I might relfect on how 2012 went at SSW. It really was another great year for SSW
with the launch of our new Metro website as well as our new SSW TV site. In 2012, SSW TV
went from zero to 30,000 unique visitors – a good start but we still have a long way to go.
Our guys and girls at SSW kept performing professionally throughout 2012, building great
.Net solutions and business applications.
The SSW project I was most proud of in 2012 was the rewrite of a very large Australian
ticketing site, because it was a real challenge and this project had so many new things we
hadn’t used in combination before, such as fixed-price with Scrum and it was written with
ASP.NET MVC 4 as well as the Telerik Sitefinity CMS.
There’s a little bit more work to go before it is released to the public, but it’s looking
good.
Our sweetest win of 2012 was with a client who engaged both us and our #1 competitor for a
week long trial. They simultaneously gave both companies the same requirements to make sure
we could well and truly walk the walk, and in the end SSW came away with the job - so we
must have impressed!
So what’s next for SSW, you ask?... (continued)
Adam Cogan, SSW
Got a comment for Adam?
Email
Adam
Adam's
blog
@Adamcogan
|
3 Day Scrum Training is back!
Intensive Professional Scrum Developer Course
|
|
Intensive 3-day Professional Scrum Developer course
Brisbane, Sydney, Adelaide, Melbourne, Perth, Canberra
Cost: $2995 +GST Pre Paid
|
Professional Scrum Developer courses teach students how to work in a team, using modern software
engineering practices, to develop
an increment of potentially releasable functionality using a specific technology platform. Students
learn to do so within the Scrum
framework doing iterative incremental development.
Classes are exercise-driven, with students working in self-organizing teams to develop "done"
increments from Product Backlog items.
Course at a Glance
This 3-day Professional Scrum Developer .NET course is a mix of lecture, demonstration, group
discussion, simulation, and hands-on
software development. The bulk of the course will be spent working as a team on a case study
application delivering increments of new
functionality in mini-sprints. Here is the course at a glance:
Note: Scrum fundamentals are not covered in this 3-day course. If you are not experienced with Scrum
fundamentals, the 5
day course is still available.
Scrum either through working on a Scrum Team or through taking part in a Professional Scrum
Foundations course.
Adelaide 8 APR 2013 |
|
Melbourne 20 MAY 2013 |
|
Sydney 03 JUNE 2013 |
|
Perth 1 JULY 2013 |
|
Canberra 12 AUG 2013 |
|
Find out more and Register
|
Video
Celebrating Our First 20 Years - Sydney .NET User Group
SSW is proud to be able to say that we have been running the Sydney .NET User Group for over 20 years
now. During that time we're had some great and memorable speakers sharing information about a range
of.NET topics.
SSW have kept evolving and we're excited that our .NET User Group is now recorded and broadcast
*Live* by our SSW TV team.
Watch more videos
on SSW TV
|
Video
How We Celebrated 20 Years of the 20th Sydney .NET User Group
Whether you were or weren't able to attend our celebratory 20th anniversary Sydney .NET User Group
last month, don't fret because we made sure to document the monumentous occassion and exactly how we
decided to celebrate it.
Watch more videos on SSW TV
|
Enterprise MVC Apps - 2 part course
Build real world applications from the ground up
Now running!
Enterprise MVC Apps Part I: Going beyond the demos
Cost: $330 +GST
Format: 1 day
|
The Model View Controller design pattern has been a proven and effective way of structuring
applications for more than 30 years. In 2007, Microsoft introduced ASP.NET MVC to the world and
since then, the framework has evolved into a mature and powerful way of writing dynamic web sites
and powerful web applications.
ASP.NET MVC provides a great way of structuring your application, ensuring a clean separation of
concerns, easy testability, and ultimate control over markup. It is quickly becoming the go-to
framework for writing .Net web applications.
Enterprise MVC Apps Part I: Going beyond the demos
This course will introduce you to the latest version of ASP.NET MVC version 4. Throughout the course,
attendees will be guided through building a full ASP.NET MVC application from scratch.
Read
more about Enterprise MVC Apps Part I
Perth: Microsoft Facility FRI 28 FEB 2013 |
|
Adelaide: Microsoft Facility THU 7 MARCH 2013 |
|
Melbourne: Microsoft Facility FRI 8 MARCH 2013 |
|
Brisbane: Microsoft Facility TUE 12 MARCH 2013 |
|
Sydney: SSW Neutral Bay WED 13 MARCH 2013 |
|
Online: Webinar - Only $80 + GST WED 13 MARCH 2013 |
|
This sellout course series will be run at 5 capital cities around Australia. Dates for Part 2 will
be announced next month.
|
Sydney .NET User Group
The best place to learn .NET for free in Sydney
PowerShell v3 for Developers - Jason Stangroome
Ever wanted to learn the in's and out's and how to's when it comes to PowerShell version 3? Well at
this month's Sydney .NET User Group, now you can! Jason Stangroome will not only be explaining the
basics of PowerShell v3, but also how developers can use PowerShell to automate daily tasks, embed
scripting into applications, and manage said applications.
About the Presenter
Jason Stangroome has years of experience bridging the gap between development and
infrastructure with his feet firmly in both camps of the Microsoft ecosystem. He has a passion for
Release Engineering, or more simply, delivering software to production frequently and reliably.
Since its inception PowerShell has been an important tool by which he strives to achieve this lofty
goal.
To see more details and RSVP, please visit our
Facebook .NET Group, our
LinkedIn .NET Group or our *NEW* Meetup
Group.
|
Can't make it to the Sydney .NET User Group?
Watch the Live stream!
|
|
Tune in from anywhere!
Sydney .NET User Group Live
6PM AEDT (UTC+11)
The team at SSWTV are now streaming our User Group sessions live. Each session will also
be published on the SSWTV site after the event so you can review what was said in the
sessions.
|
|
SSW and Telerik NerdDinner
Where nerds meet and eat
SSW and Telerik invite you to join us for pizza at The Oaks. A fantastic opportunity for networking
with peers and sharing thoughts after the Sydney .NET User Group presentation.
Sydney .Net User Group and NerdDinner proudly sponsored by:
|
Canberra .NET User Group
The best place to learn .NET for free in Canberra
Introduction to NServiceBus
There are many tools out there on the market which claim to be enterprise service buses. But only
NServiceBus incorporates true service oriented architecture and many years of experience in how to
design such systems.
Designed for collaboration between business-oriented services, NServiceBus is not a replacement for
RPC technologies like WCF.
NServiceBus is a leading open source service bus for .NET. This presentation will provide a brief
overview of integration strategies with a focus on messaging and the bus architectural style.
Demonstrations will include:
Use of the NServicebus libraries and basic concepts
The Request/response asynchronous messaging
Publish/subscribe messaging
Using the bus to coordinating processes across services using Sagas
About the Presenter
John Simons is currently responsible for the day-to-day management of the NServiceBus
Framework.
John brings over 10 years of experience building and running technological solutions that push the
envelope in geographically distributed deployment environments.
Before joining NServiceBus, John consulted on many government contracts.
To see more details and RSVP, please visit our
Facebook .NET Group, our
LinkedIn .NET Group or our *NEW* MeetUp
Group
Canberra .Net User Group proudly sponsored by:
|
Advertise with SSW
If you would like to advertise your product or service with SSW or would like to
find out more about various advertising opportunities, please email your enquiry
to<EMAIL_ADDRESS>or call: +61 2 9953 3000
|
|
February 2013
Employment
SharePoint 2013 Developer
Are you looking to establish a career working with the latest software technology for a large
range of great organisations?
SSW has been the leading Microsoft technology company in Sydney for 21 years. We require an
enthusiastic SharePoint developer to start ASAP.
Read more and Apply NOW...
Senior Web Designer
SSW is looking for a highly talented front-end Web Designer who is passionate about creating
great standards-based Web 2.0 sites. This role requires
the understanding of how people behave in certain contexts and how various stimuli and
circumstances can affect individual thought processes in social
and professional situations.
You will be working with both creative designers and the development team in various challenging
projects. This role requires someone who is able to
communicate effectively with both disciplines together with creating aesthetically pleasing
design prototypes, including graphic design, site navigation,
and layout of content.
Read more and Apply NOW...
|
|
|


We think that technology drives human potential and enterprise. There is a ton of fascinating applications of technology left to explore, which promise to advance business and human wellbeing alike.
As the next generation of industry leaders and engineers, we teach and spread what we see as vital to supporting our vision of the future. There is no shortage of brilliant individuals at Carnegie Mellon; we just bring them together into one organization.
Exciting times are ahead. Join BTG today.
WDC person
WDC person
WDC person
WDC person


| Name | Kind | Description |
| lastInPlace | attribute | |
| lastNotificationSent | attribute | |
| LastNotified | attribute | |
| LESS_THAN | attribute | |
| LESS_THAN | attribute | |
| ListCalendarData | artifact | |
| ListCalendarData | class | |
| ListCalendarData | operation | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| LocalBinder | class | |
| logActivity | operation | |
| LogSinkNotDefinedException | artifact | |
| LogSinkNotDefinedException | class | |
| LogSinkNotDefinedException | operation | |
| lpm | attribute | |
| LPM_ACTION_NAME | attribute | |
| LPM_BOOL_NAME | attribute | |
| lpmPollingPeriod | attribute | in seconds |


Deploying Service Archives
The WSO2 SOA platform has the capability of Axis2 to deploy a service as
an archive file. You can bundle all your service-related resources, service
classes, and third-party libraries and then deploy the archive file.
To deploy the service, all you have to do is locate
the archive file and upload it.
Uploading Service Archive Files
To upload your service archive file, you first need to have all the class
files and the service.xml files in the archive directory. Thereafter, you can
create the archive file.
The folder structure of the service archive file will be as follows.
Test.aar
META-INF
Services.xml
Test.class
Figure 1: Uploading service archive files
- In the navigator, under Manage/Services, click AAR
Service. The Add Service Archives
window appears.
- Provide the hierarchical path of the service. This is optional. If you want to manage
services separately, specifying a heirarchy is important. This allows you to customise
your service EPR as you wish. And also it allows you to manage multiple versions of the
same service changing only the business logic.
Example: Consider a service "Version"
If no service hierarchy -> EPR is ../services/Version
With service hierarchy foo/bar/1.0.0 -> EPR is ../services/foo/bar/1.0.0/Version
- Click Browse to locate the file you want to
upload.
- Click Upload.
The Deployed Services page
appears. Subsequently, if the service is successful, it will appear in
the Service Groups table. If the service is faulty, a Faulty Service
Groups link will appear. You can click the link to view the errors.
Testing the Service
A successful service can be easily tested through the user
interface.Several options are available to control your service.
Figure 2: Service dashboard
- In the navigator, under Manage/Services, click List.
The Deployed Services page appears.
- Click on the service name you want to test. The Service
Dashboard page appears.
- Click Try the service on the Client Operations
panel.
- A page with your service name appears. It contains the operations
available for your service.
- Give the parameters for the operations you want to invoke.
- Click Send button at the bottom of the window.
Figure 3: Try the Service
Note: Instead of using this user interface, you can also manually place
the .aar containing all the required files
into CARBON_HOME/repository/services. These archive files can be deployed
as services.
Generating the Client
You can generate the client for your service using the WSDL2Java tool in WSO2 Application Server (WSO2 AS).
Figure 4: Generating the client
- In the navigator, under Manage/Services, click List.
The Deployed Services page will appear.
- Click on the service name for which you want to generate the client.The
Service Dashboard page appears.
- Click Generate Axis2 Client. The
WSDL2Java page appears.
- Enter or select the appropriate values in the
WSDL2Java page.
- Click Generate.


Hello! I am a PhD candidate in the Department of Biostatistics at Vanderbilt University. I have a Bachelor’s in Mathematics from Baylor University. In January of 2020 I married the love of my life Paul, shown in the photo. We live in a quiet neighborhood in Nashville with our pet Beagle, Moxi.
My research interests include false discovery rates, second generation p-values, machine learning, and data science. Currently I am working under the advisement of Dr. Jeffrey D. Blume on multiple projects including identifying racial disparities in lung cancer diagnosis and treatment.
PhD Candidate in Biostatistics, expected 2022
Vanderbilt University
BS in Mathematics, 2017
Baylor University


11.1. Installing GeoMesa Cassandra¶
11.1.1. Installing Cassandra¶
The first step to getting started with Cassandra and GeoMesa is to install Cassandra itself. You can find good directions for downloading and installing Cassandra online. For example, see Cassandra’s official “Getting Started” documentation here: https://cassandra.apache.org/doc/latest/getting_started/index.html .
Once you have Cassandra installed, the next step is to prepare your Cassandra installation
to integrate with GeoMesa. First, create a key space within Cassandra. The easiest way to
do this with cqlsh
, which should have been installed as part of your Cassandra installation.
Start cqlsh
, then type:
CREATE KEYSPACE mykeyspace WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor' : 3};
This creates a key space called “mykeyspace”. This is a top-level name space within Cassandra and it will provide a place for GeoMesa to put all of its data, including data for spatial features and associated metadata.
Next, you’ll need to set the CASSANDRA_LIB
environment variable. GeoMesa uses this variable
to find the Cassandra jars. These jars should be in the lib
directory of your Cassandra
installation. To set the variable add the following line to your .profile
or .bashrc
file:
export CASSANDRA_LIB=/path/to/cassandra/lib
Finally, make sure you know a contact point for your Cassandra instance.
If you are just trying things locally, and using the default Cassandra settings,
the contact point would be <IP_ADDRESS>:9042
. You can check and configure the
port you are using using the native_transport_port
in the Cassandra
configuration file (located at conf/cassandra.yaml
in your Cassandra
installation directory).
11.1.2. Installing the GeoMesa Cassandra Data Store¶
After you’ve successfully installed and configured Cassandra, you can
move on to installing the GeoMesa Cassandra distribution.
Start by choosing or creating a directory where you want
to put it. Then cd
into that directory and type:
wget https://repo.locationtech.org/content/repositories/geomesa-releases/org/locationtech/geomesa/geomesa-cassandra-dist_2.11/$VERSION/geomesa-cassandra-dist_2.11-$VERSION-bin.tar.gz
tar xvf geomesa-cassandra-dist_2.11-$VERSION-bin.tar.gz
Note
Make sure to replace $VERSION
with the version of the distribution that you want to use, i.e. “1.3.0”.
You can browse available versions at https://repo.locationtech.org/content/repositories/geomesa-releases/org/locationtech/geomesa/geomesa-cassandra-dist_2.11/.
The directory that you just extracted is the GEOMESA_CASSANDRA_HOME
. It includes all the files
that we’ll need to use GeoMesa with Cassandra.
11.1.3. Installing GeoMesa Cassandra in GeoServer¶
The GeoMesa Cassandra distribution includes a GeoServer plugin for including
Cassandra data stores in GeoServer. The plugin files are in the
dist/gs-plugins/geomesa-cassandra-gs-plugin_2.11-$VERSION-install.tar.gz
archive within the
GeoMesa Cassandra distribution directory.
To install the plugins, extract the archive and copy the contents to the WEB-INF/lib
directory of your GeoServer installation. You will also need to copy the JARs from the
lib
directory of your Cassandra installation into the GeoServer WEB-INF/lib
directory.
Restart GeoServer after the JARs are installed.


Ahn Joon Young PD partially admits to vote rigging on 'Produce 101' season 1 & 2
by beansssAccording to updated reports on November 14, Ahn Joon Young PD of Mnet's 'Produce' series has now partially admitted to vote rigging allegations on the first and second seasons of 'Produce 101'.
Earlier during his investigation, Ahn Joon Young PD only admitted to vote manipulations on 'Produce 48' and 'Produce X 101', denying any manipulation during 'Produce 101' season 1 and 2. However, after being forwarded to prosecution on his current charges of fraud, manipulative broadcasting, etc, Ahn Joon Young PD has given a new statement, partially admitting to the likelihood of ranking manipulations from the first and second 'Produce 101' seasons.
Meanwhile, police plan on continuing their investigations into the vote manipulation suspicions behind 'Produce 101' seasons 1 and 2, as well as similar suspicions on Mnet's 'Idol School'.


--- layout: post title: Logging in a Node.js Express app with Morgan and Bunyan date: '2019-11-01T00:56:00.001+05:30' author: Sahil Rajput tags: modified_time: '2019-11-01T00:56:28.601+05:30' blogger_id: tag:blogger.com,1999:blog-5250005448924290719.post-630618454912266425 blogger_orig_url: https://www.jaadujinn.ml/2019/11/logging-in-nodejs-express-app-with.html ---


Download and Get Started with Apicurito
The easiest way to get started with Apicurito is by using Docker to quickly start up an instance, and then point your browser to it.
Pull the Apicurito image
Pull the apicurito-ui Docker image from Docker Hub as follows:
docker pull apicurio/apicurito-ui:{{ version }}
Run the Apicurito image
Run the apicurito-ui
Docker image as follows:
docker run -it -p 8080:8080 apicurio/apicurito-ui:{{ version }}
Open Apicurito in your browser
Open http://localhost:8080 in your browser.


public class SSLActiveMQMultipartyCommunicationSetup extends ActiveMQMultipartyCommunicationSetup
| Constructor and Description |
|---|
SSLActiveMQMultipartyCommunicationSetup(java.lang.String url,
java.util.List<PartyData> parties,
java.lang.String storePass)
A constructor that create an
SSLActiveMQCommunicationSetup object between the current application and any other party in the protocol. |
SSLActiveMQMultipartyCommunicationSetup(java.lang.String url,
java.util.List<PartyData> parties,
java.lang.String storePass,
boolean enableNagle)
A constructor that create an
SSLActiveMQCommunicationSetup object between the current application and any other party in the protocol. |
SSLActiveMQMultipartyCommunicationSetup(java.lang.String url,
java.util.List<PartyData> parties,
java.lang.String keyStoreName,
java.lang.String trustStoreName,
java.lang.String storePass)
A constructor that create an
SSLActiveMQCommunicationSetup object between the current application and any other party in the protocol. |
SSLActiveMQMultipartyCommunicationSetup(java.lang.String url,
java.util.List<PartyData> parties,
java.lang.String keyStoreName,
java.lang.String trustStoreName,
java.lang.String storePass,
boolean enableNagle)
A constructor that create an
SSLActiveMQCommunicationSetup object between the current application and any other party in the protocol. |
close, enableNagle, prepareForCommunication
public SSLActiveMQMultipartyCommunicationSetup(java.lang.String url, java.util.List<PartyData> parties, java.lang.String storePass) throws DuplicatePartyException, javax.net.ssl.SSLException, java.io.IOException
SSLActiveMQCommunicationSetup
object between the current application and any other party in the protocol.
It uses the default key store and trust store.url
- The url of the ActiveMQ broker.parties
- List of parties to communicate with. The first party in the list represents the current application.storePass
- The password for the key store and trust store.DuplicatePartyException
- In case there are two identical parties.java.io.IOException
- In case there is a problem with the key store or trust store file.javax.net.ssl.SSLException
- In case there is a problem during the SSL protocol initialization.public SSLActiveMQMultipartyCommunicationSetup(java.lang.String url, java.util.List<PartyData> parties, java.lang.String storePass, boolean enableNagle) throws DuplicatePartyException, javax.net.ssl.SSLException, java.io.IOException
SSLActiveMQCommunicationSetup
object between the current application and any other party in the protocol.
It uses the default key store and trust store.url
- The url of the ActiveMQ broker.parties
- List of parties to communicate with. The first party in the list represents the current application.storePass
- The password for the key store and trust store.enableNagle
- Indicates if to use Nagle's algorithm or not. For cryptographic algorithms it is much better to disable Nagle's algorithm.DuplicatePartyException
- In case there are two identical parties.java.io.IOException
- In case there is a problem with the key store or trust store file.javax.net.ssl.SSLException
- In case there is a problem during the SSL protocol initialization.public SSLActiveMQMultipartyCommunicationSetup(java.lang.String url, java.util.List<PartyData> parties, java.lang.String keyStoreName, java.lang.String trustStoreName, java.lang.String storePass) throws DuplicatePartyException, javax.net.ssl.SSLException, java.io.IOException
SSLActiveMQCommunicationSetup
object between the current application and any other party in the protocol.url
- The url of the ActiveMQ broker.parties
- List of parties to communicate with. The first party in the list represents the current application.keyStoreName
- Name of the keystore file of this party.trustStoreName
- Name of the truststore file of this party.storePass
- The password for the key store and trust store.DuplicatePartyException
- In case there are two identical parties.java.io.IOException
- In case there is a problem with the key store or trust store file.javax.net.ssl.SSLException
- In case there is a problem during the SSL protocol initialization.public SSLActiveMQMultipartyCommunicationSetup(java.lang.String url, java.util.List<PartyData> parties, java.lang.String keyStoreName, java.lang.String trustStoreName, java.lang.String storePass, boolean enableNagle) throws DuplicatePartyException, javax.net.ssl.SSLException, java.io.IOException
SSLActiveMQCommunicationSetup
object between the current application and any other party in the protocol.url
- The url of the ActiveMQ broker.parties
- List of parties to communicate with. The first party in the list represents the current application.keyStoreName
- Name of the keystore file of this party.trustStoreName
- Name of the truststore file of this party.storePass
- The password for the key store and trust store.enableNagle
- Indicates if to use Nagle's algorithm or not. For cryptographic algorithms it is much better to disable Nagle's algorithm.DuplicatePartyException
- In case there are two identical parties.java.io.IOException
- In case there is a problem with the key store or trust store file.javax.net.ssl.SSLException
- In case there is a problem during the SSL protocol initialization.


Chapter 1,"Introduction to Java Sound," gave a glimpse
into the MIDI capabilities of the Java Sound API. The present
chapter assumes you've read Chapter 1. The discussion here provides
a more detailed introduction to the Java Sound API's MIDI
architecture, which is accessed through the
javax.sound.midi
package. Some basic features of MIDI
itself are explained, as a refresher or introduction, to place the
Java Sound API's MIDI features in context. The chapter then goes on
to discuss the Java Sound API's approach to MIDI, as a preparation
for the programming tasks that are explained in subsequent
chapters. This chapter's discussion of the MIDI API is divided into
two main areas: data and devices.
The Musical Instrument Digital Interface (MIDI) standard defines a communication protocol for electronic music devices, such as electronic keyboard instruments and personal computers. MIDI data can be transmitted over special cables during a live performance, and can also be stored in a standard type of file for later playback or editing.
This section reviews some MIDI basics, without reference to the Java Sound API. The discussion is intended as a refresher for readers acquainted with MIDI, and as a brief introduction for those who are not, to provide background for the subsequent discussion of the Java Sound API's MIDI package. If you have a thorough understanding of MIDI, you can safely skip this section. Before writing substantial MIDI applications, programmers who are unfamiliar with MIDI will probably need a fuller description of MIDI than can be included in this programmer's guide. See the Complete MIDI 1.0 Detailed Specification, which is available only in hard copy from http://www.midi.org (although you might find paraphrased or summarized versions on the Web).
MIDI is both a hardware specification and a software specification. To understand MIDI's design, it helps to understand its history. MIDI was originally designed for passing musical events, such as key depressions, between electronic keyboard instruments such as synthesizers. (As mentioned in Chapter 1, MIDI data consists primarily of control events that communicate a musician's gestures. MIDI data doesn't contain the audio that results from these events.) Hardware devices known as sequencers stored sequences of notes that could control a synthesizer, allowing musical performances to be recorded and subsequently played back. Later, hardware interfaces were developed that connected MIDI instruments to a computer's serial port, allowing sequencers to be implemented in software. More recently, computer sound cards have incorporated hardware for MIDI I/O and for synthesizing musical sound. Today, many users of MIDI deal only with sound cards, never connecting to external MIDI devices. CPUs have become fast enough that synthesizers, too, can be implemented in software. A sound card is needed only for audio I/O and, in some applications, for communicating with external MIDI devices.
The brief hardware portion of the MIDI specification prescribes the pinouts for MIDI cables and the jacks into which these cables are plugged. This portion need not concern us. Because devices that originally required hardware, such as sequencers and synthesizers, are now implementable in software, perhaps the only reason for most programmers to know anything about MIDI hardware devices is simply to understand the metaphors in MIDI. However, external MIDI hardware devices are still essential for some important music applications, and so the Java Sound API supports input and output of MIDI data.
The software portion of the MIDI specification is extensive. This portion concerns the structure of MIDI data and how devices such as synthesizers should respond to that data. It is important to understand that MIDI data can be streamed or sequenced. This duality reflects two different parts of the Complete MIDI 1.0 Detailed Specification:
We'll explain what's meant by streaming and sequencing by examining the purpose of each of these two parts of the MIDI specification.The first of these two parts of the MIDI specification describes what is known informally as "MIDI wire protocol." MIDI wire protocol, which is the original MIDI protocol, is based on the assumption that the MIDI data is being sent over a MIDI cable (the "wire"). The cable transmits digital data from one MIDI device to another. Each of the MIDI devices might be a musical instrument or a similar device, or it might be a general-purpose computer equipped with a MIDI-capable sound card or a MIDI-to-serial-port interface.
MIDI data, as defined by MIDI wire protocol, is organized into messages. The different kinds of message are distinguished by the first byte in the message, known as the status byte. (Status bytes are the only bytes that have the highest-order bit set to 1.) The bytes that follow the status byte in a message are known as data bytes. Certain MIDI messages, known as channel messages, have a status byte that contains four bits to specify the kind of channel message and another four bits to specify the channel number. There are therefore 16 MIDI channels; devices that receive MIDI messages can be set to respond to channel messages on all or only one of these virtual channels. Often each MIDI channel (which shouldn't be confused with a channel of audio) is used to send the notes for a different instrument. As an example, two common channel messages are Note On and Note Off, which start a note sounding and then stop it, respectively. These two messages each take two data bytes: the first specifies the note's pitch and the second its "velocity" (how fast the key is depressed or released, assuming a keyboard instrument is playing the note).
MIDI wire protocol defines a streaming model for MIDI data. A central feature of this protocol is that the bytes of MIDI data are delivered in real time—in other words, they are streamed. The data itself contains no timing information; each event is processed as it's received, and it's assumed that it arrives at the correct time. That model is fine if the notes are being generated by a live musician, but it's insufficient if you want to store the notes for later playback, or if you want to compose them out of real time. This limitation is understandable when you realize that MIDI was originally designed for musical performance, as a way for a keyboard musician to control more than one synthesizer, back in the days before many musicians used computers. (The first version of the specification was released in 1984.)
The Standard MIDI Files part of the MIDI specification addresses the timing limitation in MIDI wire protocol. A standard MIDI file is a digital file that contains MIDI events. An event is simply a MIDI message, as defined in the MIDI wire protocol, but with an additional piece of information that specifies the event's timing. (There are also some events that don't correspond to MIDI wire protocol messages, as we'll see in the next section.) The additional timing information is a series of bytes that indicates when to perform the operation described by the message. In other words, a standard MIDI file specifies not just which notes to play, but exactly when to play each of them. It's a bit like a musical score.
The information in a standard MIDI file is referred to as a sequence. A standard MIDI file contains one or more tracks. Each track typically contains the notes that a single instrument would play if the music were performed by live musicians. A sequencer is a software or hardware device that can read a sequence and deliver the MIDI messages contained in it at the right time. A sequencer is a bit like an orchestra conductor: it has the information for all the notes, including their timings, and it tells some other entity when to perform the notes.
Now that we've sketched the MIDI specification's approach to streamed and sequenced musical data, let's examine how the Java Sound API represents that data.
MidiMessage
is
an abstract class that represents a "raw" MIDI message. A "raw"
MIDI message is usually a message defined by the MIDI wire
protocol. It can also be one of the events defined by the Standard
MIDI Files specification, but without the event's timing
information. There are three categories of raw MIDI message,
represented in the Java Sound API by these three respective
MidiMessage
subclasses:
ShortMessages
are the most common messages and
have at most two data bytes following the status byte. The channel
messages, such as Note On and Note Off, are all short messages, as
are some other messages. SysexMessages
contain system-exclusive
MIDI messages. They may have many bytes, and generally contain
manufacturer-specific instructions. MetaMessages
occur in MIDI files, but not in MIDI
wire protocol. Meta messages contain data, such as lyrics or tempo
settings, that might be useful to sequencers but that are usually
meaningless for synthesizers. As we've seen, standard MIDI
files contain events that are wrappers for "raw" MIDI messages
along with timing information. An instance of the Java Sound API's
MidiEvent
class represents an event such as might be
stored in a standard MIDI file.
The API for
MidiEvent
includes methods to set and get the event's
timing value. There's also a method to retrieve its embedded raw
MIDI message, which is an instance of a subclass of
MidiMessage
, discussed next. (The embedded raw MIDI
message can be set only when constructing the
MidiEvent
.)
As mentioned earlier, a standard MIDI file stores events that are arranged into tracks. Usually the file represents one musical composition, and usually each track represents a part such as might have been played by a single instrumentalist. Each note that the instrumentalist plays is represented by at least two events: a Note On that starts the note, and a Note Off that ends it. The track may also contain events that don't correspond to notes, such as meta-events (which were mentioned above).
The Java Sound API organizes MIDI data in a three-part hierarchy:
ATrack
is a collection of MidiEvents
,
and a Sequence
is a collection of Tracks
.
This hierarchy reflects the files, tracks, and events of the
Standard MIDI Files specification. (Note: this is a hierarchy in
terms of containment and ownership; it's not a class
hierarchy in terms of inheritance. Each of these three classes
inherits directly from java.lang.Object
.)
Sequences
can
be read from MIDI files, or created from scratch and edited by
adding Tracks
to the Sequence
(or
removing them). Similarly, MidiEvents
can be added to
or removed from the tracks in the sequence.
The previous section explained how MIDI messages are represented in the Java Sound API. However, MIDI messages don't exist in a vacuum. They're typically sent from one device to another. A program that uses the Java Sound API can generate MIDI messages from scratch, but more often the messages are instead created by a software device, such as a sequencer, or received from outside the computer through a MIDI input port. Such a device usually sends these messages to another device, such as a synthesizer or a MIDI output port.
In the world of external
MIDI hardware devices, many devices can transmit MIDI messages to
other devices and also receive messages from other devices.
Similarly, in the Java Sound API, software objects that implement
the MidiDevice
interface can transmit and receive
messages. Such an object can be implemented purely in software, or
it can serve as an interface to hardware such as a sound card's
MIDI capabilities. The base MidiDevice
interface
provides all the functionality generally required by a MIDI input
or output port. Synthesizers and sequencers, however, further
implement one of the subinterfaces of MidiDevice:
Synthesizer
or Sequencer
, respectively.
The MidiDevice
interface includes API for opening and closing a device. It also
includes an inner class called MidiDevice.Info
that
provides textual descriptions of the device, including its name,
vendor, and version. If you've read the sampled-audio portion of
this programmer's guide, this API will probably sound familiar,
because its design is similar to that of the
javax.sampled.Mixer
interface, which represents an
audio device and which has an analogous inner class,
Mixer.Info
.
Most MIDI devices are
capable of sending MidiMessages
, receiving them, or
both. The way a device sends data is via one or more transmitter
objects that it "owns." Similarly, the way a device receives data
is via one or more of its receiver objects. The transmitter objects
implement the Transmitter
interface, and the receivers
implement the Receiver
interface.
Each transmitter can be connected to only one receiver at a time, and vice versa. A device that sends its MIDI messages to multiple other devices simultaneously does so by having multiple transmitters, each connected to a receiver of a different device. Similarly, a device that can receive MIDI messages from more than one source at a time must do so via multiple receivers.
A sequencer is a device for
capturing and playing back sequences of MIDI events. It has
transmitters, because it typically sends the MIDI messages stored
in the sequence to another device, such as a synthesizer or MIDI
output port. It also has receivers, because it can capture MIDI
messages and store them in a sequence. To its superinterface,
MidiDevice
, Sequencer
adds methods for
basic MIDI sequencing operations. A sequencer can load a sequence
from a MIDI file, query and set the sequence's tempo, and
synchronize other devices to it. An application program can
register an object to be notified when the sequencer processes
certain kinds of events.
A Synthesizer
is a device for generating sound. It's the only object in the
javax.sound.midi
package that produces audio data. A
synthesizer device controls a set of MIDI channel
objects—typically 16 of them, since the MIDI specification
calls for 16 MIDI channels. These MIDI channel objects are
instances of a class that implements the MidiChannel
interface, whose methods represent the MIDI specification's
"channel voice messages" and "channel mode messages."
An application program can
generate sound by directly invoking methods of a synthesizer's MIDI
channel objects. More commonly, though, a synthesizer generates
sound in response to messages sent to one or more of its receivers.
These messages might be sent by a sequencer or MIDI input port, for
example. The synthesizer parses each message that its receivers
get, and usually dispatches a corresponding command (such as
noteOn
or controlChange
) to one of its
MidiChannel
objects, according to the MIDI channel
number specified in the event.
The MidiChannel
uses the note information in these messages to synthesize music.
For example, a noteOn
message specifies the note's
pitch and "velocity" (volume). However, the note information is
insufficient; the synthesizer also requires precise instructions on
how to create the audio signal for each note. These instructions
are represented by an Instrument
. Each
Instrument
typically emulates a different real-world
musical instrument or sound effect. The Instruments
might come as presets with the synthesizer, or they might be loaded
from soundbank files. In the synthesizer, the
Instruments
are arranged by bank number (these can be
thought of as rows) and program number (columns).
This chapter has provided a background for understanding MIDI data, and it has introduced some of the important interfaces and classes related to MIDI in the Java Sound API. Subsequent chapters show how you can access and use these objects in your application program.


表示中のページをTwitterに投稿できるブックマークレット
ブラウザのブックマークバーに登録しておけば2クリックで表示中のページをTwitterにシェアできます。
1. 以下のリンクをブラウザのブックマークバーにドラッグ・アンド・ドロップして、ブックマークとして登録します。*
BrowseNow!
2. 登録したブックマークをクリックして開きます。
3. Twitterの認証画面が開くので、連携を許可します。
4. 共有したいページでブックマークをクリックすると、Twitterにそのページでを共有できます
*ドラッグ・アンド・ドロップでブックマーク登録できないブラウザの場合
以下のURLをブックマークバーに登録してください。
Google Chrome(最新版)です。その他の環境では動作確認をしていません。
公開したいけど準備が難航しています。。
The MIT License Copyright (c) 2007 Leah Culver Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
MIT License Copyright (c) 2013-2014 Joshua Roesslein Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN aTHE SOFTWARE.
Copyright 2013-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/apache2.0/ or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Copyright JS Foundation and other contributors, https://js.foundation/ This software consists of voluntary contributions made by many individuals. For exact contribution history, see the revision history available at https://github.com/jquery/jquery The following license applies to all parts of this software except as documented below: ==== Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ==== All files located in the node_modules and external directories are externally maintained libraries used by this software which have their own licenses; we recommend you read them, as their terms may differ from the terms above.
The MIT License (MIT) Copyright (c) 2011-2018 Twitter, Inc. Copyright (c) 2011-2018 The Bootstrap Authors Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The MIT License (MIT) Copyright (c) 2013 Thomas Park Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


- {{this.investors}} Investors
- {{this.skilledPersons}} Skilled Persons
- {{this.freshers}} Freshers
Popular Categories
A better career is out there. We'll help you find it to use.
- Real estate/construction ({{this.categories[2]}})
- Travel ({{this.categories[16]}})
- Finance ({{this.categories[6]}})
- Healthcare ({{this.categories[7]}})
- Telecommunications ({{this.categories[9]}})
- Education training ({{this.categories[12]}})
- Food ({{this.categories[8]}})
- Business Services ({{this.categories[13]}})
Popular Cities
A better career is out there. We'll help you find it to use.


I was in Silicon Valley. I had worked for 5 years before I made my way out to the mecca of the tech world. I remember at one point thinking, this is it. This is the big leagues. I was happy.
I would like to start out by saying this is not in any attempt to shed a negative light on my previous employer. My goal is just to express my feelings that led me to leave the company.
I was the Sr Web Engineer at a San Francisco tech company, how many people can say that? I made friends with the people on my team I really enjoyed joking around and just working with them.
We had hectic deadlines, but I love what I do and that’s never stopped me before. My wife was pregnant at the time and decided to stay in Oklahoma with her family to help with the pregnancy. She flew in on a thursday one evening. I remember having a late meeting and it ruining our plans that night, but that was okay because I was just glad to have her around the few days… and that’s not at all one of the reasons I left. I love crazy intense deadlines . There is something very rewarding about being overworked for a week or two and then completing a pretty complex problem.
I remember being very happy and then I noticed things changing. A lot of our work was being sent overseas. We were mainly in charge of making sure the overseas team did things right, QA without any development. That was very new to me. I didn’t come to San Francisco to throw in the towel as a web developer. I came there because this was supposed to be the place where I would grow exponentially, work on amazing products, and solve real world problems.
Before I go on I would like to note something…I didn’t go to college, I made the decision not to after I got hired on as a Full time salaried web developer literally a week after my high school graduation. I talked with one of my most influential teachers at the time and she told me that if I had the opportunity to make almost the same as her right out of high school that I should take it… so I did. I don’t regret it. I love learning. I have an obsession with it… and its not just about learning things about computers. Some of my biggest interests are the brain, behavior, and learning A lot of that has to do with my aunt and my mother. They are both psychologists and I grew up listening to them talk about famous experiments and theories. I also feel that paying $20,000 a semester to learn/be talked to about things I am not passionate about is a waste of money… but society thinks otherwise… but that is for another day.
I was one day while at the company told in a pretty condescending way It was inspiring to see how I didn’t even go to college. I’m still not 100% sure what that meant, maybe it wasn’t condescending and i’m sensitive about it or something, but I don’t think so. There are some things I know I missed out on, but overall I don’t think i’ll ever regret not going to college… and I know I never want to work on a government site (which requires a degree)… those things are turning out great and don’t need me ;).
The biggest reason I decided to move was because as an Engineer it is my duty to always learn and always expand my knowledge. That wasn’t happening with the company I was working for at the time. I read a really interesting article a few weeks before I finally gave my notice, about how the really talented engineers will leave a company if they aren’t going to learn. I like to think of myself as a talented engineer and that was it. I made up my mind. I was going to put in my notice. I took a week off to think things over, especially with a kiddo about to be born, giving up a San Francisco Front End Engineer salary isn’t always an easy decision.
I’m now working as a Full Stack Engineer in Oklahoma and even though the city isn’t the mecca of development I am very happy. On any given day I could be working on server side architecture, client side, or just recently native application development. I’ve grown more in the past 6 months then I have since I first started back in 2008.
I was told by a friend I worked with at my previous employer.. “You can’t just leave when you’re unhappy with a job, there will be other jobs in San Francisco that you won’t be happy with, you just cant leave those.” My reply is that while traditionally this might have been true, for web developers, for us… we can leave. I firmly believe that as Web Developers we are in a very interesting position. We hold an extremely valuable skill. We can build almost anything in the world and that’s needed. If you don’t believe in what you’re building, what is the point? Why are you doing this? Why are you working at your current job. I’m not advocating leaving a job right away, talk with management you might find you don’t have to leave the company to be happy, for me it was the only logical choice. I believe that if you can… only apply at companies that deal with something you are passionate about otherwise in this exciting field we are no different then the guy working the 9 - 5 at the bank not because he loves it but because its a paycheck. And I will glady take a $30,000 + pay decrease to do something interesting then be miserable simply for money. Thats why I left my job in San Francisco.
Be Awesome Jeff Richardson :)