Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Activities creation and retrieval #5

Closed
wants to merge 10 commits into from

Conversation

semmons99
Copy link
Contributor

Adding activities. They are similar to mendibot's topics. However they can be handled after the fact and are not tied to specific rows in the transcript table; instead they are stored in their own activities table.

@semmons99
Copy link
Contributor Author

@mendicant/owners should we just let anyone who visits the website or irc channel setup their own activity logs?

get "/activities/:description", provides: "html" do |description|
messages = messages_for_activity(description)
render_transcript(messages)
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to merge these two methods using optional parameters:

get "/activities/:description.?:format?" do
  messages = messages_for_activity(params[:description])
  format   = format_for(params[:format] || 'html')

  render_transcript(messages, format)
end

Also, do you think the route should be namespaced to a certain channel? For example:

/:channel/activities/:description.?:format?

I know right now we are only using anita in one channel, but since we are already using that format for general logs, I think it makes sense to stay consistent and do the same thing for activities

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to try merging those two get routes again; I tried before when we were using sinatra-respond_to and it wasn't working.

I omitted the channel in the route so that a user would only need to know the name of the activity and not the channel to find it. I could go either way with requiring it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jordanbyron: It's not quite so easy to merge these two get's as one might suspect. The problem is the eager matching of the underlying regex. I've come up with three solutions.

  1. Leave it as two methods.
  2. Use a custom regex. This is what I've come up with to match the basic transactions rendering in one method %r|/(.*)/([0-9+\-:T]*)\.\.([0-9+\-:T]*)(\..*){0,1}|, something more perverse will have to be used to match descriptions.
  3. Continue to use "/:channel/:from..:to" and use some special logic to rip the extension out of :to if it's present.

I'm not really sure which I like better. Option 1 is the clearest to read, but breaks DRY. Option 2 gets us to one method, but introduces a nasty regex. Option 3 looks nice, but has to have some nasty custom logic due to eager matching. Thoughts; is there an option 4 I've missed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also come up with a matcher that doesn't have this problem. Perhaps:

get "/:channel/:from..:to/transcript.?:ext?"

It doesn't really benefit the users to do this though, which makes me think we should still focus on one of the options above.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, let me pull this down and play around with it during any downtime in my office hours today.

@jordanbyron
Copy link
Contributor

From @semmons99

should we just let anyone who visits the website or irc channel setup their own activity logs?

In a perfect world it would be nice to have some very simple permissions which can be managed both through AnitaBot and AnitaWeb. Since that is no small task I don't foresee any issues rolling this with liberal permissions at first. If we detect abuse we can easily lock it down and then roll it back out with more safe guards in place.

@semmons99
Copy link
Contributor Author

@jordanbyron: That sounds like good plan to me. I'll try and get activities completed this weekend.

@jordanbyron
Copy link
Contributor

@semmons99 how about this?

class AnitaWeb < Sinatra::Base
  # Snip ...
  get "/:channel/:from..:to.:format" do
    render_transcript(params)
  end

  get "/:channel/:from..:to", provides: "html" do
    render_transcript(params)
  end

  get "/activities/:description.:format" do
    render_activities(params)
  end

  get "/activities/:description", provides: "html" do
    render_activities(params)
  end

  private

  def render_transcript(options)
    messages = messages_for(options[:channel], options[:from], options[:to])

    render_messages(messages, options)
  end

  def render_activities(options)
    messages = messages_for_activity(options[:description])

    render_messages(messages, options)
  end

  def render_messages(messages, options)
    options[:format] ||= 'html'
    format             = format_for(params[:format])

    case format
    when :html
      haml(:transcript, locals: {messages: messages})
    when :json
      messages.to_json
    when :markdown
      erb(:transcript, locals: {messages: messages})
    else
      raise Sinatra::NotFound
    end
  end
  # Snip ...
end

Full Source

I think this is as good as it gets. It really sucks Sinatra is having trouble parsing the params. Although I'm not terribly surprised. The parameter data we are throwing at it is really yucky /jordanbyron/2012-05-23%2010:00%20UTC..2012-05-24%2014:00%20UTC.json

This at least removes the duplicate code and gives us a little more flexibility in what we want to do with the URL by just passing the parameters through to the render_XXX methods. We could have easily used ordinal methods, but this just looks so much cleaner to me.

I couldn't figure out how to create an activity (besides cracking open the DB and doing it manually) so that part of the code wasn't hand tested. Let me know what you think. 😄

@semmons99
Copy link
Contributor Author

Thanks @jordanbyron! ✨ ❤️ ✨

Used your refactored code here b882a01

@semmons99
Copy link
Contributor Author

@jordanbyron thoughts on the most recent commits? Should we push this live?


require_relative "../lib/anita"

class AnitaWeb < Sinatra::Base
InvalidDateString = BasicObject.new
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be removed, since you already have Anita::Activities:: InvalidDateString defined.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that was leftover cruft.

@jordanbyron
Copy link
Contributor

@semmons99 I made a few inline comments. There are a few other things that we need to start thinking about:

  1. Database migrations: Right now we don't have a nice way to deploy a new version of Anita and have the database migrated to the most recent schema. I'm not sure the best way to accomplish that, but it's a problem we'll need to solve.
  2. Authentication: I know I said before "do it and if we see abuse we'll fix it", but seeing the code and how wide open Anita will be, it makes me rethink that assertion. We might want to table this branch for a bit and add authentication / authorization to Anita before we "do it live". Thoughts?

It's starting to come along nicely. Nice work 😄

@semmons99
Copy link
Contributor Author

@jordanbyron:

  1. Database migrations: Right now we don't have a nice way to deploy a new version of Anita and have the database migrated to the most recent schema. I'm not sure the best way to accomplish that, but it's a problem we'll need to solve.

Maybe it's time we just grab an ORM and do this right. I've been hankering to try DataMapper, have you had any experience with it?

  1. Authentication: I know I said before "do it and if we see abuse we'll fix it", but seeing the code and how wide open Anita will be, it makes me rethink that assertion. We might want to table this branch for a bit and add authentication / authorization to Anita before we "do it live". Thoughts?

I think you're right about this too. Do we need Clubhouse brought back, or should we just do it here?

@jordanbyron
Copy link
Contributor

@semmons99

Maybe it's time we just grab an ORM and do this right. I've been hankering to try DataMapper, have you had any experience with it?

I haven't but I always like to play with new toys on OSS projects. So if that's something you want to explore, then I fully support you 👍

I think you're right about this too. Do we need Clubhouse brought back, or should we just do it here?

Oh god I think I just broke into a cold sweat 😰 No I don't want to worry about launching and maintaining clubhouse right now. Github authentication (through OmniAuth) and very, very simple authorization structure where accounts are granted moderator permission. We don't even need views to start.

@semmons99
Copy link
Contributor Author

Oh god I think I just broke into a cold sweat 😰 No I don't want to worry about launching and maintaining clubhouse right now. Github authentication (through OmniAuth) and very, very simple authorization structure where accounts are granted moderator permission. We don't even need views to start.

Thoughts on how we'd go about granting IRC users permission? Should we tie their handle to their Github ID? Should we even trust IRC since anyone can spoof an ID if it's not protected?

@jordanbyron
Copy link
Contributor

Thoughts on how we'd go about granting IRC users permission? Should we tie their handle to their Github ID? Should we even trust IRC since anyone can spoof an ID if it's not protected?

Good question. IRC is still something I use that I don't fully understand. There has to be a way where Anita::Bot can verify that a given handle is registered with Freenode before allowing it to be added. But that all seems a bit heavy handed, especially since any handle we are granting the commit bit to should be owned by someone we trust. And I'd hope those people have their nick registered.

But let's make that something we document rather than come up with a complicated systematic enforcement for.

@semmons99
Copy link
Contributor Author

Instead of trying to bring this pull request forward. I'm going to implement the authentication, then start this over from scratch. This was a good spike to start with though.

@semmons99 semmons99 closed this May 25, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants