I've made several TextCtrls and Button, but currently users of my application don't want to see them. So I have to hide them temporary (for current build).
Here they are:
class MainFrame < Wx::Frame
def initialize (parent = nil)
super nil,:title=>"sometitle",:size=>[600,600]
set_sizer Wx::BoxSizer.new Wx::VERTICAL
#tag1 = Wx::TextCtrl.new self
sizer.add_item #tag1,:flag=>Wx::RIGHT|Wx::EXPAND
#tag1.set_value 'property'
#tag1title = Wx::TextCtrl.new self
sizer.add_item #tag1title,:flag=>Wx::RIGHT|Wx::EXPAND
#tag1title.set_value 'title'
#tag2 = Wx::TextCtrl.new self
sizer.add_item #tag2,:flag=>Wx::RIGHT|Wx::EXPAND
#tag2.set_value 'description'
#tag2title = Wx::TextCtrl.new self
sizer.add_item #tag2title,:flag=>Wx::RIGHT|Wx::EXPAND
#tag2title.set_value ''
#button_parse = Wx::Button.new self
sizer.add_item #button_parse
#button_parse.label = "Parse XML"
evt_button #button_parse, :click_parse
# ......
end
# ......
end
I see nothing about it in docs and Google is also not a friend for me today.
Since they are in a sizer, then you'll be able to use Sizer#show.
Boolean show(Sizer sizer,
Boolean show = false,
Boolean recursive = false)
This works for BoxSizer and FlexGridSizer.
Related
I have a rails api that I am trying to create a live stream feature for a git gui. I have a controller and a channel for commit updates and I want to use the live stream function inside the subscribe action in the channel. Is this possible? Or is there a better Rails way to do this. I think the correct way was to use ActionCable.server.broadcast('commit_updates', { body: return_data }) inside my controller method but I am not calling my controller method anywhere. Where/how do I call it so that it is run on a client subscribing to it? or should I place the logic inside the channel?
here is my commit_updates_controller.rb
class CommitUpdatesController < ApplicationController
include ActionController::Live
require 'listen'
require 'json'
$file_path = "#{Dir.getwd}/.git/objects"
##commits = {}
##commits_array = []
##edges_array = []
def index
end
def live_stream
# get folders exlcluding ".","..", "pack","info"
folders = Dir.entries($file_path).select {|folder| /^[a-z0-9]{2}$/i.match(folder) }
folders.each do |folder|
files = Dir.children("#{$file_path}/#{folder}")
files.each do |file|
CommitUpdate.find_commit_info(folder, file, ##commits_array)
end
end
generate_edges
ActionCable.server.broadcast('commit_updates', { body: return_data })
p return_data
# listens to any changes that happen to the git folder while the program is open
listener = Listen.to($file_path) do |modified, added, removed|
# puts(modified: modified, added: added, removed: removed)
added.each do |new_file_path|
split_new_file_path = new_file_path.split("/").reject!{|item| item.empty?}
folder = split_new_file_path[split_new_file_path.length() - 2]
file = split_new_file_path[split_new_file_path.length - 1]
CommitUpdate.find_commit_info(folder, file, ##commits_array)
add_edge(##edges_array, CommitUpdate.get_commit_info(folder, file))
ActionCable.server.broadcast('commit_updates', { body: return_data })
end
end
listener.start
sleep
end
private
def generate_edges
if ##commits_array.length != 0
##commits_array.each do |commit|
add_edge(##commits_array, commit)
end
end
end
def add_edge(array, commit)
if commit[:parents] != []
commit[:parents].each {|parent| ##edges_array.push({from: parent, to: commit[:sha1]})}
end
end
def return_data
ret = {
:nodes => ##commits_array,
:links => ##edges_array
}
return ret.to_json
end
end
here is my commit_updates_channel.rb
class CommitUpdatesChannel < ApplicationCable::Channel
def subscribed
stream_from 'commit_updates'
end
end
here is my commit_updates.rb Model
class CommitUpdate < ApplicationRecord
def self.find_commit_info(folder, file, array)
file_type = self.check_sha1_type(folder, file)
if file_type == "commit"
array.push(
self.get_commit_info(folder, file)
)
end
end
def self.get_commit_info(folder, file)
author = ""
parents = []
commit_message = ""
unixtime = ""
decoded_file = `git cat-file -p #{folder}#{file}`
file_data_array = decoded_file.split("\n").reject!{|item| item.empty?}
p file_data_array
file_data_array.each do |item|
split_item = item.split(" ")
case split_item[0]
when "author"
author = split_item[1..split_item.length() - 4].join(" ")
when "parent"
parents.push(split_item[1])
when "tree"
next
when "blob"
next
when "committer"
unixtime = split_item[split_item.length - 2]
else
commit_message = split_item.join(" ")
end
end
commit_info = {
:sha1 => "#{folder}#{file}",
:parents => parents,
:commit_message => commit_message,
:author => author,
:unixtime => unixtime,
:id => "#{folder}#{file}",
:label => "#{folder}#{file[0..4]}...",
:font => "18px verdana blue",
}
return commit_info
end
private
def self.check_sha1_type(folder, file)
return `git cat-file -t #{folder}#{file}`.chomp
end
end
To use controller's live_stream, you need to request this method, for example, write js programme that is calling it periodically. Or some bash script that is calling it. Not good.
Another solution is to put live_stream logic into background job that will check commit updates every X minute. And if job finds change, it broadcasts.
And more common is to place broadcasting in model callbacks after_save, after_commit. But it looks it is not your solution.
New to Ruby-land via The Odin Project. I'm writing an algorithm to generate binary search trees from a sorted array of random numbers.
class Node
attr_accessor :value, :child_left, :child_right, :parent
def initialize (value, child_left = nil, child_right = nil, parent = nil)
#value = value
#child_left = child_left
#child_right = child_right
#parent = parent
#Checker to verify object and link creation
#puts "value: #{value}, self: #{self}, parent: #{parent}, child_left: #{child_left}, child_right: #{child_right}"
end
end
def build_tree(arry, parent = nil)
if arry.length > 2
child_left = build_tree(arry[0...arry.length/2], arry[arry.length/2])
child_right = build_tree(arry[(arry.length/2)+1..-1], arry[arry.length/2])
Node.new(arry[arry.length/2], child_left, child_right, parent)
#Can't link parent object until parent is created, but can't create child object until parent can be linked
elsif arry.length == 2
child_left = build_tree(arry[0...1], arry[1])
Node.new(arry[1], child_left, nil, parent)
elsif arry.length == 1
Node.new(arry[0], nil, nil, parent)
end
end
This results in properly generated node objects linked to their child objects, but only with the same fixnum value as the parent objects' value and not the actual parent object. It seems like a chicken/egg scenario. Either I'm committing some Object/Class creation sin here, or I simply lack the vocabulary to successfully search for a solution to my problem. Please advise.
EDIT: Maybe just a hint on some term(s) to search to point me in the right direction?
First at all, you have an issue in the constructor:
def initialize (value, childL = nil, childR = nil, parent = nil)
#value = :value
#childL = :childL
#childR = :childR
#parent = :parent
end
:something in Ruby is a Symbol, the build-in object, which is quite similar to String, but not modifiable. So, whatever you pass to Node.new, your variables will be set to :value, :childL and so on.
You probably wanted to set your class variables like this:
def initialize (value, childL = nil, childR = nil, parent = nil)
#value = value
#childL = childL
#childR = childR
#parent = parent
end
Learn more on String and Symbols in Ruby here.
I'm using Ruby 1.9.3 RSS::Maker module to generate a RSS 2.0 feed for a podcast. I'd like to start including a <content:encoded> element for show notes. This is my code for generating the RSS.
s3_bucket = AWS::S3::Bucket.find(options[:bucket])
content = RSS::Maker.make(version) do |m|
m.channel.title = options[:title]
m.channel.link = options[:link]
m.channel.description = options[:desc]
m.channel.language = options[:language]
m.channel.itunes_image = options[:image]
m.items.do_sort = true
s3_bucket.select{|object| object.key =~ /[\s\w]+\.(m4b|mp3|m4a|ogg|aac)/}.each do |audio|
i = m.items.new_item
i.link = audio.url(:authenticated => false)
i.title = audio.key.split(".")[0]
i.author = options[:author]
i.pubDate = audio.last_modified
i.guid.content = audio.etag
i.enclosure.url = i.link
i.enclosure.length = audio.content_length
i.enclosure.type = audio.content_type
# Insert content:encoded code here
end
end
For generating the <content:encoded> element I've tried:
i.encoded :content audio.metadata[:content]
i.encoded :content, audio.metadata[:content]
i.content = audio.metadata[:content]
i.content.encoded = audio.metadata[:content]
i.encoded = audio.metadata[:content]
i.encoded.content = audio.metadata[:content]
None of these work and most throw a NoSuchMethod exception - which is not surprising based on the documentation of the RSS::Maker module.
Is there a way using RSS::Maker to add arbitrary elements with a namespace?
You’re looking for i.content_encoded.
The documentation isn’t too great, so I used i.methods to get a list of methods I can use on feed items. methods works on all objects.
The list is quite long, so you most likely only want to show methods you can write to, i.e. something like this:
RSS::Maker.make("2.0") do |ma|
puts ma.items.new_item.methods.keep_if { |m|
m.to_s.end_with?("=")
}.join("\n")
end
I am getting the following error when trying to call tweet.entities in my twitter feed controller.
private method `entities' called for #Twitter::Status:0x94d4bf4
I have no methods called entities in the code, I even did a full file search to check.
I either need to rename the entities part of the object or somehow find where this so called private method is or circumnavigate it somehow. My method within my twitter_feeds controller is as follows:
def hometimeline
#user = User.find(current_user.id)
tweets = #user.tweeting.user_timeline(count: '10', include_entities: true)
parsed_tweets = []
i = 0
tweets.each do |tweet|
more = Hash.new
more['test'] = tweet
internal_hash = Hash.new
mappings = {"source" => "fixed"}
another = more['test']
boo = Array(tweet)
#newhash = Hash[twee.map {|k, v| [mapping[k], v] }]
#newhash = Hash[more.map {|k, v| [mappings[k], v] }]
#newhash = Hash[tweet.map {|k, v| [mappings[k] || k, v] }]
internal_hash['parsed_text'] = tweet.entities
internal_hash['id'] = tweet.id
internal_hash['raw_text'] = tweet.text
internal_hash['name'] = tweet.user.name
internal_hash['screen_name'] = tweet.user.screen_name
internal_hash['user_id'] = tweet.user.id
internal_hash['user_image_url'] = tweet.user.profile_image_url
parsed_tweets << internal_hash
i = i + 1
end
respond_to do |format|
format.json { render json: parsed_tweets }
end
end
Essentially I am sending a set of parsed tweets to the client and want to achieve link wrapping etc. on the server.
Is there any way I can find where the code thinks this method is or is there a way to make it not private or ignore it so I can call tweet.entities.
EDIT: One extra point to note is that I did have an entity model and entities controller but have deleted them and still get this.
Thanks
Turns out this error is caused by the Twitter gem and they have methods for calling the entities object namely, tweet.urls, tweet.user_mentions etc. rather than tweet.entities.user_mentions as I would have thought.
Docs are here http://rdoc.info/gems/twitter/Twitter/Tweet
In my apps/controllers/model_controller.rb I have (names of models/methods changed to protect the innocent):
def background_sync
#background_task_uid = Model.async_process_model_cache({:name => 'name'})
#model_sync = ModelSync.new # Adds a new record in the queue of pending jobs
#model_sync.process_id = #background_task_uid # Puts the background process id into the new ModelSync record
#model_sync.save
end
In app/workers/model_worker.rb:
def process_model_cache(options={})
[long background task]
result = Workling::Return::Store.set(options[:uid], 'done')
result = Workling::Return::Store.get(options[:uid]) #=> 'done'
end
Notice that the set and get are functioning properly here within this worker. The problem is later on...
Back in app/views/model/index.html.rb, I have a prototype helper polling a request to the same controller to determine whether the background job is complete:
<%= periodically_call_remote( :url => { :action => :background_complete }, :frequency => 5, :update => 'status_div') %>
And in apps/controllers/model_controller.rb, the function for checking the status of the background job:
def background_complete
#background_task_uid = ModelSync.find(:last)
if #background_task_uid
#background_task_uid.each do |task|
unless task.process_id == "" || task.process_id.nil?
#result = Workling::Return::Store.get(task.process_id) #=> nil
if #result.nil?
task.destroy
end
else
task.destroy
end
unless #result.nil?
render :text => "<span style='font-size:12px;margin-left:20px;'>"+#result+"</span>"
else
#result = "none" if #result.nil?
render :text => "<span style='font-size:12px;margin-left:20px;'>"+#result+"</span>"
end
end
end
end
And finally, in config/environments/development.rb:
Workling::Return::Store.instance = Workling::Return::Store::MemoryReturnStore.new
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
(Note that I've tried running this with and without the last line commented. If commented out, Workling reverts to Spawn rather than Starling.)
So the problem is that I get nil from this line in background_complete:
#result = Workling::Return::Store.get(task.process_id) #=> nil
I know it is a year since you asked this question, but just getting into Starling now, myself, so didn't see this till now.
But it looks like your problem was (from development.rb):
Workling::Return::Store.instance = Workling::Return::Store::MemoryReturnStore.new
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
It needed to be:
Workling::Return::Store.instance = Workling::Return::Store::StarlingReturnStore.new
Workling::Remote.dispatcher = Workling::Remote::Runners::StarlingRunner.new
At least for the benefit of those google searchers out there... :)
Found the answer to this question. The fix is to remove the Workling::Return::Store.instance line from config/environments/development.rb
Then replace the get AND set calls as follows:
In app/workers/model_worker.rb:
store = Workling::Return::Store::StarlingReturnStore.new
key, value = #uid, #progress
store.set(key, value)
In app/controllers/models_controller.rb:
store = Workling::Return::Store::StarlingReturnStore.new
#result = store.get(task.process_id)
Obviously, there is a way to declare a shortcut in environments.rb to avoid calling a new StarlingReturnStore each time, but I'm out of my depth because I can't make that work.
Anyway, this fix works for me. I'm getting the output from each background job to report via set to the get in the controller, which then gets captured by the AJAX call and reported to the page via RJS.
Nice!