ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <mixflame> Does anyone know a Crystal function to remove the HTML from a string?
<FromGitter> <mixflame> hopefully img links and a's would be turned into just a textual link
<FromGitter> <mixflame> not required
<FromGitter> <Blacksmoke16> https://github.com/straight-shoota/sanitize related
<FromGitter> <Blacksmoke16> idt there's anything in the stdlib for it thi
<FromGitter> <Daniel-Worrall> `XML.parse(html).content` is a great start
Human_G33k has quit [Ping timeout: 246 seconds]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<FromGitter> <mixflame> nice @Daniel-Worrall !!!
<FromGitter> <mixflame> has anyone done an RSS feed generator in Crystal? anyone got source for that? similar to the ruby gem "rss" with the "builder" style API
<FromGitter> <mixflame> seems that didn't work @Daniel-Worrall :(
<FromGitter> <mixflame> left the "<br />"'s in
<FromGitter> <Daniel-Worrall> `.gsub("<br />", "")`
<FromGitter> <Daniel-Worrall> You can also `.squeeze(' ') to reduce large blocks of whitespace
<FromGitter> <Blacksmoke16> and thats a no on the rss thing. But should be fairly trivial to implement with `XML::Builder`
<FromGitter> <mixflame> ahh thanks guyz
<FromGitter> <mixflame> I think XML.parse(html) requires a valid document format... sorry... This is the content of a "contenteditable" div with document.execCommands in functions making random HTML strings for an HTML chat (that's also linked to IRC via a bridge.)
<FromGitter> <mixflame> all in Crystal :D
<FromGitter> <Blacksmoke16> Oh, you mean to parse red?
<FromGitter> <Blacksmoke16> RSS
<FromGitter> <mixflame> No no, to generate a feed, sorry
<FromGitter> <mixflame> I am talking about two things at once
<FromGitter> <mixflame> Stripping HTML from IRC/Webchat and RSS feed of a gallery of images
<FromGitter> <Blacksmoke16> I thought so. So yea should be pretty easy then
chachasmooth has quit [Ping timeout: 250 seconds]
chachasmooth has joined #crystal-lang
chachasmooth has quit [Ping timeout: 245 seconds]
chachasmooth has joined #crystal-lang
DTZUZU_ has joined #crystal-lang
DTZUZU has quit [Ping timeout: 240 seconds]
deavmi has quit [Read error: Connection reset by peer]
deavmi_ has joined #crystal-lang
<FromGitter> <mixflame> cool cool thanks @Blacksmoke16
postmodern has quit [Quit: Leaving]
hendursaga has quit [Ping timeout: 240 seconds]
hendursaga has joined #crystal-lang
<FromGitter> <naqvis> When using modules as mixin, how to invoke same method of specific included module? `super` will invoke the last included module in the list, but how to go above that ? ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60aa2875a10461235d94246b]
<FromGitter> <naqvis> i couldn't find a way to namespace it to particular module leve, or some other way to invoke a method in particular sequence
_whitelogger has joined #crystal-lang
<jhass> I don't see a way. Either make B know about A or provide per module aliases, rep_a, rep_b
<FromGitter> <naqvis> Thanks jhass
richbridger has quit [Remote host closed the connection]
<FromGitter> <naqvis> does `BitArray#to_slice` truncates the off bits? ⏎ https://play.crystal-lang.org/#/r/b75z
<FromGitter> <naqvis> shouldn't it be returning the same size?
<jhass> I think BitArray#size is number of bits and Slice#size is byte count. BitArray.new(16) makes a that a little more evident
<FromGitter> <naqvis> Thanks jhass
<FromGitter> <naqvis> What would be the best way to convert `BitArray` to integer representation? assuming `BitArray` is equivalent to c++ `std::bitset`
<jhass> not sure about "best way" but stuffing the to_slice into an IO::Memory and then doing TheInt.from_io I'd expect to work
<FromGitter> <naqvis> but wouldn't that take into consideration endianness?
<FromGitter> <naqvis> i settled on `IO::ByteFormat::LittleEndian.decode(UInt16,b.to_slice)`
<jhass> well yeah, thing is BitArray is not an integer internally but an byte array
<jhass> so you have to decide the endianess you want anyhow
DTZUZU_ has quit [Read error: Connection reset by peer]
DTZUZU_ has joined #crystal-lang
hightower2 has joined #crystal-lang
<hightower2> Hey a recurring theme I see is that I have '@var = default_val' at class level, and then inside some initialize() methods I want to make it possible to pass @var as optional argument (which, if unspecified, would default to the class-level default)
<hightower2> Is there any way to do this without repeating the default value, and without doing something like this in initialize:
<hightower2> ``` var.try { |v| @var = v } ```
<FromGitter> <Blacksmoke16> just give it the default as part of the initializer no?
<FromGitter> <Blacksmoke16> and no as part of its declaration
<FromGitter> <Blacksmoke16> not*
<hightower2> Yes but if I have multiple initializes I need to repeat it over and over
<FromGitter> <Blacksmoke16> thats right yes
<hightower2> ok, tx
<FromGitter> <Blacksmoke16> OR what you could do it make it nilable in all the constructors
<FromGitter> <Blacksmoke16> then in the final constructor can do like `@var = var || 123`
<hightower2> Yes, although even that fails due to "Inidirect initialization not supported", so I can't use it for anything that's non-nil
<hightower2> (or have to resort to property! ... )
<FromGitter> <Blacksmoke16> no that should deff work
<FromGitter> <Blacksmoke16> you make the declaration of the ivar not nil, but make the constructor args nilable
<hightower2> interesting, let me try
<hightower2> I'm getting the error I mentioned. Could you show an example of what you had in mind?
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/b76n
<FromGitter> <Blacksmoke16> you're probably using `self` before assigning it
<hightower2> hm hm... well interesting idea but again far from elegance I hoped for
<FromGitter> <Blacksmoke16> another option is use a private method as the default
<hightower2> yes, I was hoping to avoid to have to write anything, and just have the declaration apply whenever possible... probably not possible with macros, and even with them it'd be abusing them
<hightower2> ok great, thanks for input/ideas
<hightower2> yeah it's all circling around the issue... another way to solve it would be through just finally supporting that "indirect initialization"
<hightower2> So all the defaults could be defined in a single function (or however is best in a particular case), and that function or functions could be called both during initialize and later, for example when updating certain values on existing objects etc.
<FromGitter> <Blacksmoke16> got some example code of what you're doing and the error?
<hightower2> Not really, it'
<hightower2> Not really, it's more of an "it's always this same thing" for me... in my style of coding this keeps coming up constantly... but well, I tried to raise the importance of this issue a couple times in the past with no success
<FromGitter> <alex-kampa> Hi, does anyone here know how to use Gzip::Writer to write to a string instead of a file?
<FromGitter> <Blacksmoke16> hightower2 idt it's something that could be supported well
<FromGitter> <Blacksmoke16> like what happens if you have an object with `@var : Int32`, and you pass that to another obj to be set via like `obj.var = 123` but something forgets to set it. At the least it would be unsafe
<FromGitter> <Blacksmoke16> which maybe would be ok, but id argue it's still kinda a smell
<hightower2> alex-kampa: give it e.g. IO::Memory.new as first argument instead of a filename?
<FromGitter> <Blacksmoke16> @alex-kampa maybe just use `String.build do do |io|`
<jhass> not that String should be abused much for binary data
<jhass> I wish we kept enforcing UTF8 for it
<jhass> so, I call X/Y question
<hightower2> Blacksmoke16 yes I mean, the compiler would do the same checks that it currently does within initialize(), it would just additionally support following through to other methods called from initialize(), instead of working on initialize only... It could do the simplest check where it only follows a method if it's called unconditionally
<FromGitter> <Blacksmoke16> :shrug: maybe
<FromGitter> <Blacksmoke16> id be curious to see what you're doing that it comes up so often
<FromGitter> <alex-kampa> > *<hightower2>* @alex-kampa: give it e.g. IO::Memory.new as first argument instead of a filename? ⏎ ⏎ Tried this, but it throws an error: ⏎ `` content = "some random string" ⏎ io = IO::Memory.new ... [https://gitter.im/crystal-lang/crystal?at=60aa72220ff6de262b24b696]
<jhass> Why do you need to have a string of gzip content? What are you planning to do with the string?
<FromGitter> <alex-kampa> payload of a remote call
<jhass> remote call using what?
<FromGitter> <alex-kampa> get or post over https
<jhass> I don't follow how a HTTP GET would have a payload. For POST you can just pass a IO to HTTP::Client.post's body argument
<jhass> so payload = IO::Memory.new; Compress::Gzip::Writer.open(payload) {|io| io << "payload" }; HTTP::Client.post(..., body: payload)
<jhass> IO.copy is for copying one IO to another
<FromGitter> <alex-kampa> ok got it, thanks!
DTZUZU_ has quit [Read error: Connection reset by peer]
DTZUZU has joined #crystal-lang
<FromGitter> <alex-kampa> ... of course now I'd like to un-gzip this with Gzip::Reader without using files and and that is not immediately obvious either :-)
<FromGitter> <Blacksmoke16> use the response body_io as the source and uncompress it into an `IO::Memory`
<jhass> Also note that if the server sends the right headers HTTP::Client will decompress automatically
<jhass> (in hindsight HTTP::Client.compress= really should've been .decompress=)
<hightower2> Teacher asks a student: What is your greatest strength? -Hindsight. -That's not gonna help us at all! -Yes, I see that now. :-)
<FromGitter> <alex-kampa> Re hindsight - in French there is the expression "L'esprit de l'escalier" - staircase wit. Cf https://en.wikipedia.org/wiki/L%27esprit_de_l%27escalier
<FromGitter> <alex-kampa> So how do I convert a String into an IO ?
<FromGitter> <Blacksmoke16> write the string to an `IO::Memory`
<FromGitter> <alex-kampa> what's the specific command to do that?
<FromGitter> <Blacksmoke16> `IO::Memory.new "the string"`
<jhass> if the string is coming from external, just don't make it a string in the first place, have whatever's needing the io get the io the string came from. If the string is static/constant just write it to the target IO directly
<FromGitter> <alex-kampa> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60aa88ef0ff6de262b24eab9]
<FromGitter> <alex-kampa> this still does not work: Can't write to Compress::Gzip::Reader (IO::Error)
<FromGitter> <alex-kampa> In the doc there is something about .gets_to_end which I don't understand
<jhass> why do you have s being gzipped things
<FromGitter> <alex-kampa> > *<jhass>* if the string is coming from external, just don't make it a string in the first place, have whatever's needing the io get the io the string came from. If the string is static/constant just write it to the target IO directly ⏎ ⏎ for now the plan is that only part of the data will be compressed, so can't take the entire io. although that may change.
<jhass> that sounds... brittle
<jhass> what's the outer encoding look like?
<FromGitter> <alex-kampa> It's a json. depending on what's in the uncompressed part, we decide whether it's even necessary to decompress the rest.
Genie has joined #crystal-lang
<FromGitter> <alex-kampa> ok it works now ... looks like I'm just not that good at following instruction, it was all in the doc: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60aa8b9edf5c362d4be87135]
Genie has left #crystal-lang [#crystal-lang]
<jhass> wouldn't be my choice to do it that way (gzip as a json string) honestly
<jhass> I prefer something where you wouldn't even need to read the things you don't care about into memory
<FromGitter> <alex-kampa> Thanks for helping out @Blacksmoke16 and hightower2
sagax has joined #crystal-lang
<FromGitter> <alex-kampa> > *<jhass>* I prefer something where you wouldn't even need to read the things you don't care about into memory ⏎ ⏎ when receiving a get or post request, don't see how it could only be received partially ... do you know of a way?
<jhass> HTTP::Client has block forms for all the helper methods, the yielded response object will have a #body_io and only the headers were consumed from the socket
<jhass> the body is all in your control to read from the socket via #body_io
<jhass> if you exit the block without doing the socket is just closed
<jhass> so yeah, you can totally only partially read a response body
<jhass> but then it's ugly to depend on your JSON being serialized in a particular order, so I really wouldn't use JSON in that case
<jhass> I mean a full JSON document as a header followed by some separator could be legit I guess. You'd want to first write the length of that header though and in that case you're midway to custom binary protocol anyhow already
DTZUZU_ has joined #crystal-lang
<jhass> also with using the IO interface like that allows you to for example wrap it into a gzip reader and then IO.copy the whole affair into a file, never reading the entire thing into memory
<jhass> part of why these interfaces seem so hard to use for you because they're made for working with streams like that, not pushing things through strings
DTZUZU has quit [Ping timeout: 240 seconds]
<jhass> they basically are designed to make it hard to fully read stuff into memory because you quite rarely actually want that with things that are big enough that you'd care about compression for example
DTZUZU_ has quit [Ping timeout: 240 seconds]
DTZUZU_ has joined #crystal-lang
DTZUZU has joined #crystal-lang
DTZUZU_ has quit [Ping timeout: 260 seconds]
<FromGitter> <rishavs> Need some help with cookies. I am able to send back Set-cookie header in my responses but my browser is rejecting them without any console error ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60aac1780ff6de262b256422]
<FromGitter> <rishavs> do I need https even for development?
<FromGitter> <rishavs> @oprypin:matrix.org , I tried Lax and strict. both samesite values give me errors on the browser console ⏎ `Some cookies are misusing the recommended “SameSite“ attribute 2 ⏎ Cookie “usertoken” has been rejected because it is in a cross-site context and its “SameSite” is “Lax” or “Strict”.`
<FromGitter> <rishavs> I thought I would try samesite = None with secure, but even that is not working :(
<FromGitter> <oprypin:matrix.org> @rishavs: please start by specifying which domain(s) are being used in the browser
<FromGitter> <rishavs> I am working on a SPA. the spa is on 127.0.0.1: 8080 and my crystal http server is on 127.0.0.1:3000
<oprypin> rishavs, yea i guess those are separate sites, so you'd get the same problem in production then
richbridger has joined #crystal-lang
<FromGitter> <alex-kampa> > *<jhass>* part of why these interfaces seem so hard to use for you because they're made for working with streams like that, not pushing things through strings ⏎ ⏎ Thanks for the feedback, I will think about this!
<FromGitter> <rishavs> @oprypin:matrix.org , so no way other than setting up https then?
<FromGitter> <oprypin:matrix.org> @rishavs: i think it's not related to https
<FromGitter> <Blacksmoke16> secure cookies wouldnt be sent over non https connections fwiw
<FromGitter> <Blacksmoke16> but given that error, it seems they are?
<FromGitter> <oprypin:matrix.org> @Blacksmoke16: link i sent says localhost is included into secure
<FromGitter> <Blacksmoke16> ahh makes sense
<FromGitter> <Blacksmoke16> good to know
<FromGitter> <rishavs> sigh... still no idea how to proceed. this samesite feature has broken my earlier working code :/
<FromGitter> <rishavs> Will goto sleep and try gain with fresh eye tomorrow. Thanks for all the help Oleh and George
DTZUZU_ has joined #crystal-lang
DTZUZU has quit [Ping timeout: 265 seconds]